Содержит ли объект-генератор, возвращаемый функцией-генератором, ссылку на объект-функцию? Другими словами, можно ли реализовать 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__
. Возможно ли это, или ссылка уже потеряна, как только генератор был создан?
1 ответ
Итератор генератора не относится к функции генератора. В этом можно убедиться, сохранив слабую ссылку на функцию с помощью weakref.ref
< / а>:
>>> import weakref
>>> def gen():
... yield 1
...
>>> ref = weakref.ref(gen)
>>> gen_iter = gen()
>>> del gen
>>> ref() is None
True
В отличие от обычных ссылок, weakref.ref
не задерживает сбор того, на что он ссылается. Если референт (gen
) все еще жив, ref()
будет gen
. Если референт был собран, ref()
будет None
. Как видите, weakref был очищен, чего не произошло бы, если бы 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
True
Похожие вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.
__del__
наDummy
, который печатает "до свидания". Не могли бы вы добавить дополнительные объяснения этого использованияweakref.ref
и того, как это работает?