从生成器函数返回的生成器对象是否持有对函数对象的引用?换句话说,是否有可能实现可以这样做的magic_fn:
>>> def gen():
... yield 1
... yield 2
...
>>> gen.attr = 'potato'
>>> g = gen()
>>> del gen
>>> next(g)
1
>>> magic_fn(g, 'attr')
'potato'生成器具有对代码对象(g.gi_code)、帧(g.gi_frame)和名称(g.__name__)的引用。代码对象甚至具有与gen.__code__相同的内存地址。
但是,假设它尚未被垃圾收集,我无法找到一种访问gen.__dict__的方法。是否有可能,或者在生成器创建后,链接就已经丢失了?
发布于 2016-12-24 02:11:46
生成器迭代器不引用生成器函数。通过使用weakref.ref保持对函数的弱引用,您可以看到这一点。
>>> import weakref
>>> def gen():
... yield 1
...
>>> ref = weakref.ref(gen)
>>> gen_iter = gen()
>>> del gen
>>> ref() is None
True与普通引用不同,weakref.ref不会延迟它所引用的内容的集合。如果referent (gen)还活着,ref()将是gen。如果已经收集了引用,则ref()为None。如您所见,弱引用已被清除,如果gen_iter仍然引用gen,则不会发生这种情况。
类似地,您可以显示生成器迭代器没有保留对函数的__dict__的引用,或者任何其他允许它检索存储在函数的__dict__中的项的引用链
>>> class Dummy(object):
... pass
...
>>> def gen():
... yield 1
...
>>> gen.attr = Dummy()
>>> ref = weakref.ref(gen.attr)
>>> gen_iter = gen()
>>> del gen
>>> ref() is None
Truehttps://stackoverflow.com/questions/41309689
复制相似问题