Excerpt in relation to the generator - another type is returned

There is this code:

def f(): return 3 return (i for i in range(10)) x = f() print(type(x)) # int def g(): return 3 for i in range(10): yield i y = g() print(type(y)) # generator 

Why does f return int when there is a return generator instruction? I think the yield and generator expression returns both generators (at least when the return 3 operator is deleted), but there are some other rules for compiling functions when there is a returned generator expression and the second time there is a yield keyword inside?

This has been tested in Python 3.3.

+4
source share
4 answers

As soon as you use the yield in the function body, it becomes a generator. A call to the generator function returns this generator object. This is no longer a normal function; instead, the generator object took control.

From yield expression documentation :

Using the yield expression in a function definition is enough to force that definition to create a generator function instead of a normal function.

When the generator function is called, it returns an iterator, known as a generator. This generator then controls how the generator functions. Execution begins when one of the generator methods is called.

In a regular function, calling this function immediately switches control to that function body, and you simply check the result of the function specified by its return . In the generator function, return still signals the end of the generator function, but this causes a StopIteration exception StopIteration . But until you call one of the four generator methods ( .__next__() , .send() , .throw() or .close() ), the body of the generator function does not execute at all.

For your specific function f() , you have a regular function containing a generator. The function itself has nothing special, except that it ends earlier when return 3 is executed. The expression of the generator on the next line is in itself, it does not affect the function in which it is defined. You can define it without function:

 >>> (i for i in range(10)) <generator object <genexpr> at 0x101472730> 

Using a generator expression creates a generator object, similar to using the yield function in a function, then calling this function creates a generator object. So you could call g() in f() with the same result as using the generator expression:

 def f(): return 3 return g() 

g() is still a generator function, but using it in f() does not make f() a generator function. Only yield can do this.

+9
source
 def f(): return 3 return (i for i in range(10)) 

coincides with

 def f(): return 3 

The second returned statement never starts, just having a generator expression inside f does not make it a generator.

+2
source
 def f(): return 3 #unreachable code below return (i for i in range(10)) 

I believe that you meant:

 def f(): yield 3 yield from (i for i in range(10)) 
+1
source

Returning a generator does not make f a generator function. A generator is just an object, and generator objects can be returned by any function. If you want f be a generator function, you must use yield inside the function, as was the case with g .

0
source

Source: https://habr.com/ru/post/1483033/


All Articles