使用弱引用实现组合

2024-03-29 08:51:27 发布

您现在位置:Python中文网/ 问答频道 /正文

弱引用可以用来传递复合对象属性吗?假设您有一个属性为a的类。现在代码的任何部分都可以获取对a的引用,但是,如果由A组成的类实例被删除,则A必须被删除,但如果它在其他地方被引用,则不会被删除。可以用弱引用实现这种行为,就像对A的唯一强引用由组合对象拥有一样?你知道吗

class B:
 def __init__(self):
   self.A = SomeClass()

Tags: 对象实例代码self属性initdef地方
3条回答

Python delete将对象标记为potential删除,并减少引用计数器-只有在引用计数器达到零时才会发生最终删除。你知道吗

弱引用用于避免保留实例,而不是确保在引用对象时删除对象。你知道吗

SomeClass()实例的所有strong引用都被删除时,实例将只从内存中被删除(任何不是弱引用的引用都是强引用)。你知道吗

如果B().A属性是对SomeClass()实例的唯一引用,那么当B().A引用反弹到其他对象或清除时,该实例将被删除(如果B()被删除,则B().A属性将自动清除),因为SomeClass()的引用计数降至0。你知道吗

换句话说,如果B().A是对SomeClass()的弱引用,并且没有其他SomeClass()的引用,则取消引用B().A将返回None,因为SomeClass()已经被删除。你知道吗

但是,在B().A外部使用弱引用可以确保B().A是对该SomeClass()实例的唯一的强引用。你知道吗

如果我理解正确,您的用例是这样的:

b = B()

def reset_b():
    global b
    b = B() # drops the reference to b, so it (and b.A) should be garbage collected

def get_a():
    return b.A

您关心的是,从get_a返回的保存的A引用在b重置后仍然有效。如果这是对的,那么弱引用可能是一种解决方法:

import weakref

def get_a():
    return weakref.proxy(b.A)

如果proxy对象是在它所引用的b.A对象被删除之后使用的,那么它将引发大多数操作的异常。你知道吗

我不确定这是一个好的设计,虽然。更好的解决方案可能是简单地记录get_a的结果不应该长期缓存。相反,每当需要新的引用时,应该再次调用它。这不需要任何复杂的引用方案或异常处理,而且更容易考虑和测试。你知道吗

相关问题 更多 >