So I have been wracking my brain trying to figure this out for like 2 hours. As I understood it, when I define a module with functions, and move to a new file, I can import that module. Then to call a function from that module I can do something like module_name.function_name(inputs). Note that there is only one period!
So, there is a module called itertools. When I import itertools
, I can call itertools.chain
(list or list of lists) and it will create an iterator object for me. HOWEVER, now this is the part I don't get, I can ALSO call itertools.chain.from_iterable
and it will ALSO create a different iterator object for me. I dont get how this is possible? How can itertools.chain
and itertools.chain.from_iterable
both be functions that return something, and how would I go about creating a module like that?
How can there be 2 periods in 1 function call when the stuff before the first period isnt a class? (I can also import classes from a module and then call methods defined within the class using Class_name.method_name(inputs). however I'm pretty sure chain is a function and not a class because it returns an output!!)
As @khelwood said in his/her comment, itertools.chain
is a class, and therefore you are just calling a classmethod through itertools.chain.from_iterable
: https://docs.python.org/fr/3/library/itertools.html#itertools.chain.from_iterable
EDIT (I didn't realize first link was in french, apologies) https://docs.python.org/3/library/itertools.html#itertools.chain.from_iterable
itertools.chain.from_iterable
isn't a normal method, its a classmethod.
When classmethod is called, it gets the class as the first argument instead of the instance of that class (as we normally do with methods). This means we can use the class and its properties inside that method rather than a particular instance. Class methods are useful when you need to have methods that aren't specific to any particular instance.
There are several ways an object can be callable like a function and also have attributes.
def chain(...):
# logic of itertools.chain
chain.from_iterable = lambda *args: # logic of itertools.chain.from_iterable
__call__
method:class ChainClass:
def __call__(self, ...):
# logic of itertools.chain
def from_iterable(self, ...):
# logic of itertools.chain.from_iterable
chain = ChainClass()
# now chain is callable and chain.from_iterable is callable
itertools.chain
is actually a class: class chain:
def __init__(self, ...):
# logic of itertools.chain
@classmethod
def from_iterable(cls, ...):
# logic of itertools.chain.from_iterable
For itertools.chain
, it is actually a class (though it is built-in, not written in Python). When you call itertools.chain([])
, you are instantiating the class.
You can verify that:
import itertools
ch = itertools.chain([])
isinstance(ch, itertools.chain) # True
Code example for itertools Chain in Python using Class
Reference: Need to implement the Python itertools function “chain” in a class
Code
File: my_itertools.py
class chain:
def __init__(self, *iterables): # Normal Constructor
self.list = iter(iterables) # iterator for iterables
self.current = iter(next(self.list)) # current is first iterable in list
def __iter__(self):
while True:
try:
yield next(self.current) # loop through current
except StopIteration: # out of current, set current to next
try:
# set next iterable
self.current = iter(next(self.list))
except StopIteration:
break # Done, since have gone through list of all
# iterables
@classmethod
def from_iterable(cls, iterables): # Alternative constructor
return cls(*iterables) # returns a chain object
Usage
File: main.py
import my_itertools
a = [1, 2, 3]
b = [4, 5, 6]
for i in my_itertools.chain(a, b):
print('chain: ', i)
# Outputs
chain: 1
chain: 2
chain: 3
chain: 4
chain: 5
chain: 6
for i in my_itertools.chain.from_iterable([a, b]):
print('from iterable ', i)
# Outputs:
from iterable 1
from iterable 2
from iterable 3
from iterable 4
from iterable 5
from iterable 6
y = list(my_itertools.chain([1, 2, 3]))
print('y: ', y)
# Output: y: [1, 2, 3]
print(f'Type {type(my_itertools.chain([1, 2, 3]))}')
Output: Type <class 'my_itertools.chain'>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.