在Objective C中,通过使用弱引用来避免上述问题。在C++中,我们不会调用代理的delete方法。我在这里找到了Python的weakref模块链接:http://docs.python.org/library/weakref.html。似乎一个合理的方法可能是使用该模块创建一个弱引用来引用实例变量,但我不确定。
由于我在Google上搜索这个问题没有找到答案,我想知道在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.
编辑:
阅读了一些回复后,我决定澄清我的问题。我知道Python有垃圾收集。我不确定的是它是否会对循环引用的对象执行垃圾收集。我的担忧来自Python文档中以下段落:
CPython实现细节: CPython当前使用引用计数方案和(可选的)延迟检测循环链接的垃圾收集,它会在大多数对象变得无法访问时立即收集,但不能保证收集包含循环引用的垃圾。请参见gc模块的文档以获取有关控制循环垃圾收集的信息。其他实现的行为不同,并且CPython可能会更改。在对象变得无法访问时不要依赖于立即完成(例如:始终关闭文件)。
可以在这里找到原始形式的文本: http://docs.python.org/reference/datamodel.html 粗体为我的设置。
下面的帖子提供了有关循环引用对象问题的更清晰的解释,以及为什么该问题将防止对这些对象进行垃圾收集(至少在典型设置中): http://www.electricmonk.nl/log/2008/07/07/python-destructor-and-garbage-collection-notes/。
此外,我刚刚看到亚历克斯·马特利在以下问题的回复中解释了Python用户是否应该担心循环引用: Should I worry about circular references in Python? 从他的答案中,我得出结论,即使循环引用对象最终会被垃圾收集但会有开销。它是否显著取决于程序。
此外,他提到使用Python的weakref模块,但没有明确说明如何使用。
因此,我想添加以下问题以澄清一些未解决的问题:
- 文档说对循环引用的对象不能保证进行垃圾收集。但是从回复中看来,似乎不是这种情况。那么我是否误解了这段文字,还是有进一步的细节我错过了?
- 我认为,如Alex的回复和我的问题所述,使用弱引用将完全避免这个问题的开销?
再次感谢回复。