@JoelCornettの答えは基本を完全にカバーしています。これは少し複雑なバージョンであり、いくつかの微妙な問題に役立つ可能性があります。
特定のクラスのすべての「ライブ」インスタンスにアクセスできるようにする場合は、以下をサブクラス化します(または、独自の基本クラスに同等のコードを含めます)。
from weakref import WeakSet
class base(object):
def __new__(cls, *args, **kwargs):
instance = object.__new__(cls, *args, **kwargs)
if "instances" not in cls.__dict__:
cls.instances = WeakSet()
cls.instances.add(instance)
return instance
これは、@JoelCornettが提示したより単純な実装で発生する可能性のある2つの問題に対処します。
の各サブクラスはbase
、独自のインスタンスを個別に追跡します。親クラスのインスタンスリストにサブクラスインスタンスを取得することはなく、1つのサブクラスが兄弟サブクラスのインスタンスに遭遇することはありません。ユースケースによっては、これは望ましくない場合がありますが、セットを分割するよりも、セットをマージして戻す方がおそらく簡単です。
instances
セットはクラスのインスタンスへの弱参照を使用するため、コード内の他の場所のインスタンスに他のすべての参照を再割り当てした場合でも、del
簿記コードによってガベージコレクションが妨げられることはありません。繰り返しになりますが、これは一部のユースケースでは望ましくない場合がありますが、すべてのインスタンスを本当に永久に存続させたい場合は、ウィークセットの代わりに通常のセット(またはリスト)を使用するのは簡単です。
いくつかの便利でダンディなテスト出力(セットは、うまく印刷されないという理由だけでinstances
常に渡されます):list
>>> b = base()
>>> list(base.instances)
[<__main__.base object at 0x00000000026067F0>]
>>> class foo(base):
... pass
...
>>> f = foo()
>>> list(foo.instances)
[<__main__.foo object at 0x0000000002606898>]
>>> list(base.instances)
[<__main__.base object at 0x00000000026067F0>]
>>> del f
>>> list(foo.instances)
[]