3

次のコードは、"good" のみを出力します。ジェネレータ関数が実行されないのはなぜですか? pdb で、「handlers1」を実行した後、スクリプトが f1 の定義を含む行に到達するが、関数内に入らないことに気付きました。逆に、「GeneratorExit: None」が返されます。

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 に答える