Python 使用弱引用实现组合
弱引用可用于传递复合对象属性?假设您有一个属性为a的类。代码的任何部分现在都可以获取对a的引用,但如果由a组成的类实例被删除,则必须删除a,但如果它在其他地方被引用,则不会删除。用弱引用实现这种行为可以吗?对的唯一强引用由组合对象拥有Python 使用弱引用实现组合,python,composition,Python,Composition,弱引用可用于传递复合对象属性?假设您有一个属性为a的类。代码的任何部分现在都可以获取对a的引用,但如果由a组成的类实例被删除,则必须删除a,但如果它在其他地方被引用,则不会删除。用弱引用实现这种行为可以吗?对的唯一强引用由组合对象拥有 class B: def __init__(self): self.A = SomeClass() Python delete将对象标记为可能删除,并递减引用计数器-只有在引用计数器达到零时才会发生最终删除。弱引用用于避免保留实例,而不是确保在引用对象时
class B:
def __init__(self):
self.A = SomeClass()
Python delete将对象标记为可能删除,并递减引用计数器-只有在引用计数器达到零时才会发生最终删除。弱引用用于避免保留实例,而不是确保在引用对象时删除对象
SomeClass()
实例只有在所有强引用被删除时才会从内存中删除(任何不是弱引用的引用都是强引用)
如果B().A
属性是对SomeClass()
实例的唯一引用,那么当B().A
引用反弹到其他对象或清除时,该实例将被删除(如果B()
被删除,则B().A
属性将自动清除),当SomeClass()
的引用计数下降到0时
换句话说,如果B()
但是,在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)
如果在其引用的b.A
对象被删除后使用代理
对象,则大多数操作都会引发异常
但我不确定这是否是一个好的设计。更好的解决方案可能是简单地记录get\u A
的结果不应该长期缓存。相反,每当需要新的引用时,应该再次调用它。这不需要任何复杂的引用方案或异常处理,而且更容易思考和测试。如果删除了A,为什么必须删除组件?如果删除了A,则必须删除A。这与问题的意思相反。在任何情况下,这都不会发生:B
实例引用了SomeClass
对象,因此它使它保持活动状态。仅在CPython中。这是一个实现特性,而不是语言规范的要求。