私は以下の原理で動作何かを実装しようとしています:2つのオブジェクト間の循環参照に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()
しかし、私が手を:
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
インスタンスがGCedを取得し、から削除したため、私の実装が正しくないことを理解WeakValueDictionary
。
循環参照がContainer
とThing
の間になるのを防ぐために、これを実現する方法はありますか?
編集:上記のコードを上記のものに変更した場合、循環参照の問題は解決しますか?
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)
'シング(自己)は' '自己*前*と呼ばれることに注意してください.dic [thing] = 'が実行されます。 – kennytm
はい、私は通常のdictで問題があります。厚い卵のようなものです。しかし、私は 'dic [thing] = None'でこれを解決できます。 –
" Thing'インスタンスはGCを取得する可能性があります。まあ、**はガベージコレクションされています。したがって、 'KeyError'。 –