classを反復したい場合は、反復をサポートするメタクラスを定義する必要があります。
x.py:
class it(type):
def __iter__(self):
# Wanna iterate over a class? Then ask that class for iterator.
return self.classiter()
class Foo:
__metaclass__ = it # We need that meta class...
by_id = {} # Store the stuff here...
def __init__(self, id): # new isntance of class
self.id = id # do we need that?
self.by_id[id] = self # register istance
@classmethod
def classiter(cls): # iterate over class by giving all instances which have been instantiated
return iter(cls.by_id.values())
if __name__ == '__main__':
a = Foo(123)
print list(Foo)
del a
print list(Foo)
最後にわかるように、インスタンスを削除してもオブジェクト自体には何の影響もありませんby_id
。weakref
sを使用して対処できます
import weakref
そして、する
by_id = weakref.WeakValueDictionary()
. このように、この場合のように、値を保持する「強力な」参照がある限り、値は保持されa
ます。の後del a
、オブジェクトを指している弱い参照しかないため、それらを gc することができます。
sに関する警告WeakValueDictionary()
のため、以下を使用することをお勧めします。
[...]
self.by_id[id] = weakref.ref(self)
[...]
@classmethod
def classiter(cls):
# return all class instances which are still alive according to their weakref pointing to them
return (i for i in (i() for i in cls.by_id.values()) if i is not None)
少し複雑に見えますが、オブジェクトではなくオブジェクトを取得するようにしてくださいweakref
。