我想问在Python中使用委托模式是否会导致循环引用,如果是的话,实现它以确保对象及其委托将被垃圾收集的最佳方法是什么?
在 Objective C 中,通过使用委托的弱引用来避免上述问题。在 C++ 中,我们不会对委托调用删除。我在这里找到了 Python 弱引用模块的链接:http://docs.python.org/library/weakref.html http://docs.python.org/library/weakref.html。似乎一种合理的方法可能是创建一个弱引用来引用使用此模块的实例变量,但我不确定。
由于我用谷歌搜索了这个问题,但无法找到答案,我想知道这是否是Python中的一个问题,或者是否有一个我不知道的通用解决方案(不需要weakref模块)的?另外,我在询问之前确实搜索了 stackoverflow,但我发现的问题要么涉及循环导入,要么涉及一般的委托模式,而不是特定于 Python 和循环引用问题。
预先感谢您的回复。
下面列出了一些玩具示例的代码,以帮助说明我的问题。我已经以这种方式实现了代码并且它有效,但我不确定内存最后是否被垃圾收集。
class A(object):
def __init__(self):
self.delegate = None
# Some other instance variables that keep track of state for performing some tasks.
def doSomething(self):
if self.delegate is not None:
self.delegate.doSomething()
else:
print('Cannot perform task because delegate is not set.')
# Other methods not shown.
class B(object):
def __init__(self):
self.a = A() # Need to keep object 'a' from garbage collected so as to preserve its state information.
self.a.delegate = self # Is this a circular reference? How to 'fix' it so that A and B will eventually be garbage collected?
def doSomething(self):
print('B doing something')
# Other methods not shown.
EDIT:
看了一些回复后,我决定澄清一下我的问题。我知道Python有垃圾收集功能。我不确定它是否会对循环引用的对象执行垃圾收集。我的担忧源于 Python 文档中的以下段落:
CPython 实现细节:CPython 目前使用
具有(可选)延迟检测的引用计数方案
循环链接的垃圾,一旦大多数对象被回收,它就会收集它们
变得无法访问,但是不保证收集垃圾
包含循环引用。请参阅 gc 模块的文档
有关控制循环垃圾收集的信息。其他
实现的行为有所不同,CPython 可能会发生变化。不依赖
当对象变得无法访问时立即完成对象(例如:
始终关闭文件)。
该段落的原始形式可以在这里找到:http://docs.python.org/reference/datamodel.html http://docs.python.org/reference/datamodel.html大胆的设置是我的。
以下文章对循环引用对象的问题以及为什么它会阻止这些对象的垃圾收集(至少在典型设置中)提供了更清晰的解释:http://www.electricmonk.nl/log/2008/07/07/python-destructor-and-garbage-collection-notes/ http://www.electricmonk.nl/log/2008/07/07/python-destructor-and-garbage-collection-notes/.
此外,我刚刚看到 Alex Martellli 对以下问题的答复:Python 用户是否应该担心循环引用:我应该担心 Python 中的循环引用吗? https://stackoverflow.com/questions/2428301/should-i-worry-about-circular-references-in-python从他的回答中,我了解到,尽管循环引用的对象最终会被垃圾收集,但会有开销。是否重要取决于程序。
此外,他提到使用Python的weakref模块,但没有明确说明如何使用。
因此,我想补充以下问题来澄清一些未解决的问题:
- 文档说垃圾收集不能保证循环
引用的对象。但从回复看来,并不是这样的
案件。那么我是否误解了这段文字,或者还有进一步的内容吗?
我错过了哪些细节?
- 我想使用弱引用,如亚历克斯的回复和我的
问题是,是否可以完全避免开销问题?
再次感谢您的回复。