使用收益率时没有“打印”输出?

时间:2018-07-13 17:55:22

标签: python

我正在使用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的输出?

4 个答案:

答案 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()