简体   繁体   中英

Is a generator the callable? Which is the generator?

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:

  1. 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.

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM