"Yield None"如何在 Python Cookbook, 2nd Edition 的示例中工作?



我正在查看python食谱中的示例代码,第二版(第9.8节(。

我不再流利的python-休息了很多年。

我对微螺纹感兴趣,这是一个。

的示例

阅读代码时,我无法从"无屈服"起作用的头部或尾巴。

如果我理解它 - 它会导致函数的变量保存在堆栈上,以便可以在随后的调用中恢复函数的状态。

对于编写的代码段,这似乎太神奇了 - 感谢您的帮助。

注意:我无法运行

import signal
# credit: original idea was based on an article by David Mertz
# http://gnosis.cx/publish/programming/charming_python_b7.txt
# some example 'microthread' generators
def empty(name):
    """ This is an empty task for demonstration purposes. """
    while True:
        print ("<empty process>", name)
        yield None
def terminating(name, maxn):
    """ This is a counting task for demonstration purposes. """
    for i in xrange(maxn):
        print ("Here %s, %s out of %s" % (name, i, maxn))
        yield None
    print ("Done with %s, bailing out after %s times" % (name, maxn))
def delay(duration=0.8):
    """ Do nothing at all for 'duration' seconds. """
    import time
    while True:
        print ("<sleep %d>" % duration)
        time.sleep(duration)
        yield None
class GenericScheduler(object):
    def __init__(self, threads, stop_asap=False):
        signal.signal(signal.SIGINT, self.shutdownHandler)
        self.shutdownRequest = False
        self.threads = threads
        self.stop_asap = stop_asap
    def shutdownHandler(self, n, frame):
        """ Initiate a request to shutdown cleanly on SIGINT."""
        print ("Request to shut down.")
        self.shutdownRequest = True
    def schedule(self):
        def noop( ):
            while True: yield None
        n = len(self.threads)
        while True:
            for i, thread in enumerate(self.threads):
                try: thread.next( )
                except StopIteration:
                    if self.stop_asap: return
                    n -= 1
                    if n==0: return
                    self.threads[i] = noop( )
                if self.shutdownRequest:
                    return
if __name__== "__main__":
    s = GenericScheduler([ empty('boo'), delay( ), empty('foo'),
                           terminating('fie', 5), delay(0.5),
                        ], stop_asap=True)
    s.schedule( )
    s = GenericScheduler([ empty('boo'), delay( ), empty('foo'),
                           terminating('fie', 5), delay(0.5),
                        ], stop_asap=False)
    s.schedule( )

老实说,我认为这个片段过于复杂,无法掌握这个概念。 yield Noneyield 1yield any_other_value

没有什么不同

当Python遇到 farter 在功能代码中,它将此函数转换为特殊用途对象,该对象与常规函数的行为不同。在每个yield上,它确实返回值并保存当前状态。请参阅我的代码示例,其中包含一些调试信息(在python 2.7上测试,可能在Python 3.x上不起作用(,希望它会有所帮助

def gen():
    yield 1
    yield
    yield 2
g = gen()
print('what is a generator')
print(type(g))
print('generator contents')
print(dir(g))
print('generator gi_frame object')
print(dir(g.gi_frame))
print('code line')
print(g.gi_frame.f_lineno)
print('step 1')
print(next(g))
print('generator state after step 1')
print(g.gi_frame.f_lineno)
print('step 2')
print(next(g))
print('generate state after step 2');
print(g.gi_frame.f_lineno)

print('last step')
print(next(g))
print(g.gi_frame.f_lineno)
print('nothing left')
try:
    print(next(g))
except StopIteration as e:
    print('got StopIteration')
print(g.gi_frame)

输出:

what is a generator
<type 'generator'>
generator contents
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
generator gi_frame object
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'f_back', 'f_builtins', 'f_code', 'f_exc_traceback', 'f_exc_type', 'f_exc_value', 'f_globals', 'f_lasti', 'f_lineno', 'f_locals', 'f_restricted', 'f_trace']
code line
1
step 1
1
generator state after step 1
2
step 2
None
generate state after step 2
3
last step
2
4
nothing left
got StopIteration
None

最新更新