Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)?

like image 868
du369 Avatar asked Feb 24 '14 08:02

du369


People also ask

How do you define a generator?

A generator is a special type of function which does not return a single value, instead, it returns an iterator object with a sequence of values. In a generator function, a yield statement is used rather than a return statement. The following is a simple generator function.

What takes place when a generator function calls yield?

When you call a function that contains a yield statement anywhere, you get a generator object, but no code runs. Then each time you extract an object from the generator, Python executes code in the function until it comes to a yield statement, then pauses and delivers the object.

How do I print the contents of a generator?

Use list() to print a generator expression. Call list(object) with object as the generator expression to create a fully computed list of the generator's output. Call print(list) with list as the previous result to print the generator expression.

What is send type in generator?

Sending Values to GeneratorsThe send() method resumes the generator and sends a value that will be used to continue with the next yield . The method returns the new value yielded by the generator. The syntax is send() or send(value) . Without any value, the send method is equivalent to a next() call.


2 Answers

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.

like image 153
user2357112 supports Monica Avatar answered Oct 03 '22 07:10

user2357112 supports Monica


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

like image 37
Mariy Avatar answered Oct 03 '22 07:10

Mariy