3

以下代码仅打印“好”。为什么不执行生成器函数?我注意到 pdb 在执行 'handlers1' 后,脚本到达了 f1 定义的行,但随后没有进入函数内部。相反,它返回“GeneratorExit:无”。

class foo:

   def f0(self, s):
      print s

   def f1(self, s):
      print "not " + s
      yield 1

   def run(self):
      handlers={0 : self.f0, 1 : self.f1}
      handlers[0]('good')
      handlers[1]('good')

bar = foo()
bar.run()

为什么会发生这种情况?是否可以以类似的动态方式调用生成器函数?

4

4 回答 4

4

调用生成器函数的方式与调用普通函数的方式不同。生成器函数在调用时不会运行,而是返回一个迭代器。此迭代器在传递给next()或在其他迭代上下文中使用时,会调用原始函数:

>>> def f1(s):
...   print(s)
...   yield
... 
>>> it = f1("hello")
>>> next(it)
hello
>>> 

为了跟进另一个答案中的讨论,这是一种调用常规函数或生成器函数的方法:

>>> def f0(s):
...   print s
... 
>>> def f1(s):
...   print s
...   yield
... 
>>> try: next(f0("hello"))
... except TypeError: pass
... 
hello
>>> try: next(f1("hello"))
... except TypeError: pass
... 
hello
>>> 
于 2013-09-13T03:00:17.453 回答
3

您需要调用next,否则生成器中的代码将根本无法运行。

class foo:

   def f0(self, s):
      print s

   def f1(self, s):
      print "not " + s
      yield 1

   def run(self):
      handlers={0 : self.f0, 1 : self.f1}
      handlers[0]('good')
      handlers[1]('good').next()

bar = foo()
bar.run()

打印“好”然后“不好”。

于 2013-09-13T03:04:14.373 回答
1

当您使用生成器函数时,它只返回一个迭代器。您应该尝试调用生成器的 next 方法来执行生成器函数的主体。尝试这个:

class foo:
   def f0(self, s):
      print s

   def f1(self, s):
      print "not " + s
      yield 1

   def run(self):
      handlers={0 : self.f0, 1 : self.f1}
      for _, func in handlers.iteritems():
          res = func('good')
          if hasattr(res, 'next'):
              next(res)

bar = foo()
bar.run()
于 2013-09-13T02:57:34.713 回答
1

生成器函数被调用,但调用生成器函数并不会立即执行任何操作。阅读文档,其中解释了:

当调用生成器函数时,实际参数以通常的方式绑定到函数局部形式参数名称,但不会执行函数体中的代码。

于 2013-09-13T02:58:22.803 回答