Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No 'print' output when using yield?

Tags:

python

I am implementing a web scraper using the scrapy framework. In order to implement pipeline, yield is necessary when parsing the response from the scraper. It seems to me that when using yield at the end of a function, all output from print statements is suppressed and replaced by the generator object.

def testFunc(arg1):
    print arg1
    yield arg1

testFunc('This does not print.')

Results in:

In [7]: testFunc('Will this print?')
Out[7]: <generator object testFunc at 0x10d636d20>

Simply commenting the yield restores the print call:

def testFunc(arg1):
    print arg1

Results in:

In [10]: testFunc('Will this print?')
Will this print?

How do I maintain print output when using yield?

like image 281
ph0t0n Avatar asked Jul 13 '18 17:07

ph0t0n


People also ask

Does yield stop the function?

A return in a function is the end of the function execution, and a single value is given back to the caller. When the function is called and it encounters the yield keyword, the function execution stops. It returns generator object back to the caller.

What does the yield function do in Python?

yield in Python can be used like the return statement in a function. When done so, the function instead of returning the output, it returns a generator that can be iterated upon. You can then iterate through the generator to extract items.

How to yield two values in Python?

If you want to return multiple values from a function, you can use generator functions with yield keywords. The yield expressions return multiple values. They return one value, then wait, save the local state, and resume again.

What does the expression print not 0 return?

"Returning" and "printing" are different things. print will always return None and print whatever you give it, if called. The thing that surprises you is the behaviour of Boolean operators, not print . x or y is defined as "The value of x if truthy; else, the value of y ".


Video Answer


3 Answers

Calling a generator function as in testFunc(1) simply creates a generator instance; it does not run the body of the code. Generators are iterators, so you can pass them to next(). In the case of Generators, the action of its __next__() is essentially to run up to the next yield statement and return the yielded value. So you can do things like:

>>> gen = testFunc(1)
>>> next(gen)
Will this print?
1

or, as others have noted, you can loop over it (though this is not necessary if you want to just yield one value).

When you define a generator, you can almost think of calling a generator as creating an instance of some class that implements a very specific state machine that works as an iterator. To be clear, that's not actually how it works, but it can be written equivalently that way. Generators are a much more elegant way to do this in most cases, however.

like image 76
Iguananaut Avatar answered Oct 20 '22 07:10

Iguananaut


The print statements will be executed whenever the generator is iterated over. If you just want to see what the iterator prints, you can call it in a list comprehension without saving the result.

def testFunc(arg1):
    print arg1
    yield arg1

>>> [_ for _ in testFunc(1)]
1
[1]
like image 6
bphi Avatar answered Oct 20 '22 07:10

bphi


I don't think anyone gave the answer to "How do I maintain print output when using yield?" from the perspective of the programmer writing the function.

Here it is:

def testFunc(arg1):
    print(arg1)
    def foo():
         yield arg1
    return foo()
like image 2
Bananach Avatar answered Oct 20 '22 09:10

Bananach