dynamic call of functions and generator function (python)

青春壹個敷衍的年華 提交于 2019-12-23 19:27:55

问题


The following code only prints "good". Why the generator function is not executed? I noticed with pdb that after executing 'handlers1' the script reaches the line with f1's definition but then does not get inside the function. Conversely, it's returned '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()

Why this happens? Is it possible to call generator functions in a similar dynamic way?


回答1:


You need to call next or the code in the generator won't run at all.

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

That prints "good" then "not good".




回答2:


One does not invoke generator functions the same way one invokes normal functions. A generator function, when invoked, does not run but instead returns an iterator. This iterator, when passed to next() or used in other iteration contexts, invokes the original function:

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

To follow up on the discussion in another answer, here is a way to invoke either a regular function or a generator function:

>>> 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
>>> 



回答3:


The generator function is called, but calling a generator function doesn't immediately do anything. Read the documentation, which explains:

When a generator function is called, the actual arguments are bound to function-local formal argument names in the usual way, but no code in the body of the function is executed.




回答4:


When you cann a generator function, it only returns an iterator. You should try to call the generator's next method to execute the body of generator function. Try this:

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


来源:https://stackoverflow.com/questions/18777544/dynamic-call-of-functions-and-generator-function-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!