我正在使用scrapy框架实现网络刮板。为了实现流水线,在解析来自刮板的响应时,yield
是必需的。在我看来,在函数末尾使用yield
时,print
语句的所有输出都会被抑制,并由生成器对象代替。
def testFunc(arg1):
print arg1
yield arg1
testFunc('This does not print.')
结果:
In [7]: testFunc('Will this print?')
Out[7]: <generator object testFunc at 0x10d636d20>
只需注释yield
即可恢复print
调用:
def testFunc(arg1):
print arg1
结果:
In [10]: testFunc('Will this print?')
Will this print?
使用print
时如何保持yield
的输出?
答案 0 :(得分:3)
每当迭代生成器时,都会执行print语句。如果只想查看迭代器打印的内容,则可以在列表理解中调用它,而无需保存结果。
def testFunc(arg1):
print arg1
yield arg1
>>> [_ for _ in testFunc(1)]
1
[1]
答案 1 :(得分:2)
调用 testFunc(1)
中的生成器函数只是创建一个生成器实例。它不会运行代码的主体。生成器是迭代器,因此您可以将它们传递给next()
。对于Generators,其__next__()
的操作本质上是运行到下一个yield
语句并返回产生的值。因此,您可以执行以下操作:
>>> gen = testFunc(1)
>>> next(gen)
Will this print?
1
或者,正如其他人所指出的,您可以在其上循环(尽管如果只想产生一个值,则不必这样做)。
在定义生成器时,几乎可以想到调用生成器就是创建某个类的实例,该类实现了一个非常特定的状态机,该状态机充当迭代器。需要明确的是,它实际上不是如何工作,但是可以用这种方式等效地编写。但是,在大多数情况下,生成器是一种更为优雅的方法。
答案 2 :(得分:0)
@bphi击败了我,但以下是他的解决方案起作用的详细说明:
每当函数中包含yield
时,在使用yield
创建的生成器之前,该正文中的其余代码将不会运行。这只是yield
在python中的工作方式的副产品。如果您想使用与yield
相同的功能执行代码,只需将其置于空的for
循环中即可,如bphi演示
答案 3 :(得分:0)
我认为没有人给出“使用产量时如何保持打印输出?”的答案。从程序员编写函数的角度来看。
这里是:
def testFunc(arg1):
print(arg1)
def foo():
yield arg1
return foo()