Python 使用弱引用实现组合

Python 使用弱引用实现组合,python,composition,Python,Composition,弱引用可用于传递复合对象属性?假设您有一个属性为a的类。代码的任何部分现在都可以获取对a的引用,但如果由a组成的类实例被删除,则必须删除a,但如果它在其他地方被引用,则不会删除。用弱引用实现这种行为可以吗?对的唯一强引用由组合对象拥有 class B: def __init__(self): self.A = SomeClass() Python delete将对象标记为可能删除,并递减引用计数器-只有在引用计数器达到零时才会发生最终删除。弱引用用于避免保留实例,而不是确保在引用对象时

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

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中。这是一个实现特性,而不是语言规范的要求。