gpt4 book ai didi

python - 两个对象之间的循环引用是否需要使用weakref?

转载 作者:行者123 更新时间:2023-11-30 22:56:22 25 4
gpt4 key购买 nike

我正在尝试实现一些遵循以下原则的东西:

from weakref import WeakValueDictionary

class Container(object):
def __init__(self):
self.dic = WeakValueDictionary({})
def put_in(self, something):
self.dic[something] = Thing(self, something)

class Thing(object):
def __init__(self, container, name):
self.container = container
self.name = name

def what_I_am(self):
print("I am a thing called {}".format(self.name))

pot = Container()
pot.put_in('foo')
pot.dic['foo'].what_I_am()

但我明白:

  File "C:/Users/jacques/ownCloud/dev/weakref.py", line 26, in <module>
pot.dic['foo'].what_I_am()
File "C:\Program Files\Anaconda3\lib\weakref.py", line 131, in __getitem__
o = self.data[key]()
KeyError: 'foo'

我知道我的实现不正确,因为 Thing 实例被 GC 并从 WeakValueDictionary 中删除。

有什么方法可以实现类似的目的,以防止 ContainerThing 之间的循环引用?

编辑:如果我将上面的代码更改为下面的代码,是否可以解决循环引用问题?

from weakref import proxy

class Container(dict):
def put_in(self, something):
self[something] = Thing(self)

class Thing(object):
def __init__(self, container):
self.container = proxy(container)

def what_is_it(self):
print("I am a thing called {}".format(self))

def __getattr__(self, name):
try: #Look up the Thing instance first
return object.__getattribute__(self, name)
except AttributeError: #Try to find the attribute in container
return self.container.__getattribute__(name)

def __format__(self, spec):
(name,) = (key for key, val in self.container.items() if self == val)
return name

pot = Container()
pot.location = 'Living room'
pot.put_in('foo')
pot['foo'].what_is_it()
print(pot['foo'].location)

最佳答案

WeakValueDictionary 的关键在于,一旦对象不再使用,它​​的键就会自动删除。

紧接着

self.dic[thing] = Thing(self)

WeakValueDictionary 之外不再有对 Thing 对象的引用,因此您看到的行为是正确且符合预期的。

如果您希望 key 可访问,请将 WeakValueDictionary 替换为常规 dict。或者,确保存在对该事物的引用,例如通过返回它或在其他地方引用它。

关于python - 两个对象之间的循环引用是否需要使用weakref?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37055383/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com