A generator is simply a function which returns an object on which you can call next, such that for every call it returns some value, until it raises a StopIteration exception, signaling that all values have been generated. Such an object is called an iterator.
>>> def myGen(n):
... yield n
... yield n + 1
...
>>> g = myGen(6)
I quoted this from Understanding Generators in Python?
Here is what I am trying to figure out:
Which is the generator? myGen
or myGen(6)
?
According to the quote mentioned above, I think the generator should be myGen
. And myGen(6)
is the returned iterator object. But I am really not sure about it.
When I tried this:
>>> type(myGen) <type 'function'> >>> type(g) # <1>this is confusing me. <type 'generator'> >>> callable(g) # <2> g is not callable. False >>> callable(myGen) True >>> g is iter(g) # <3> so g should an iterable and an iterator True # at the same time. And it will be passed as an argument >>> for i in g: # to built-in function `next()` in a "for...in..." loop. print i # (is that correct?) 6 7
So, according to <1>
and <2>
, g
's type is 'generator' and it is not callable. But generators are callable, and calling a generator gets you an iterator object What's going on here?
When I was searching for answers, I run into Every time you define a function python creates a callable object.
So, can I say something like this? when the function myGen
is defined, myGen
is a name referring to a callable object which is an instance of a class that has a __call__
method . In this case, myGen
is a generator, and myGen(6)
is the returned iterator when myGen
is called.
But why does type(g)
return <type 'generator'>
at all? And this returned iterator
thing also looks suspicious to me since there is no return
statement in the function.
Isn't it that Functions always return something (at least None
, when no return-statement was reached during execution and the end of the function is reached) ?
The terminology is unfortunately confusing, as "generator" is so commonly used to refer to either the function or the returned iterator that it's hard to say one usage is more correct. The documentation of the yield statement says
The yield statement is only used when defining a generator function , and is only used in the body of the generator function. Using a yield statement in a function definition is sufficient to cause that definition to create a generator function instead of a normal function.
When a generator function is called, it returns an iterator known as a generator iterator , or more commonly, a generator .
The original PEP introducing the concept says
Note that when the intent is clear from context, the unqualified name "generator" may be used to refer either to a generator-function or a generator-iterator .
If you want to make a clear distinction, use "generator function" for the function and "generator iterator" for the iterator.
1) myGen
is function which when invoked returns a generator object - so yes, myGen(6)
is a generator object.
2) Generators supply __iter__
and next()
: docs
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.