Ich versuche, etwas zu implementieren, die unten auf dem Prinzip funktioniert:Erfordert der zirkulare Bezug zwischen zwei Objekten die Verwendung von weakref?
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()
Aber ich bekomme:
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'
Ich verstehe, dass meine Implementierung nicht korrekt ist, weil Thing
Instanz GCed bekommt und aus der gelöscht WeakValueDictionary
.
Gibt es eine Möglichkeit, etwas zu erreichen, um den Zirkelbezug zwischen Container
und zu vermeiden?
Edit: Wenn ich den obigen Code für den folgenden ändern, würde es das zirkuläre Referenzproblem lösen?
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)
Beachten Sie, dass 'Thing (Selbst-)' * vor * genannt 'Selbst .dic [ding] = 'wird ausgeführt. – kennytm
Ja, das ist das Problem, das ich mit einem normalen Diktat habe. Es ist ein bisschen wie das Dick und das Ei. Aber ich kann es lösen mit 'dic [Sache] = None' –
" Thing "Instanz kann GC" na ja, es ** ist ** Müll gesammelt werden. Daher der 'KeyError'. –