これを行うには、クラスのすべてのインスタンスを見つける何らかの方法が必要です。これを行う 1 つの方法は、クラス自体にそのインスタンスを追跡させることです。残念ながら、クラス内のすべてのインスタンスへの参照を保持するということは、それらのインスタンスがガベージ コレクションされないことを意味します。幸いなことに、Python には がweakref
あり、オブジェクトへの参照は保持されますが、Python のメモリ管理への参照としてカウントされないため、通常どおりインスタンスをガベージ コレクションできます。
インスタンスのリストを更新するのに適した場所は、__init__()
メソッド内です。__new__()
関心の分離が少しきれいであることがわかった場合は、それを行うこともできます。
import weakref
class Foo(object):
_instances = []
def __init__(self, value):
self.value = value
cls = type(self)
type(self)._instances.append(weakref.ref(self,
type(self)._instances.remove))
@classmethod
def iterinstances(cls):
"Returns an iterator over all instances of the class."
return (ref() for ref in cls._instances)
@classmethod
def iterattrs(cls, attr, default=None):
"Returns an iterator over a named attribute of all instances of the class."
return (getattr(ref(), attr, default) for ref in cls._instances)
今、あなたはこれを行うことができます:
f1, f2, f3 = Foo(1), Foo(2), Foo(3)
for v in Foo.iterattrs("value"):
print v, # prints 1 2 3
記録として、私はこれが一般的に悪い考えである、および/または実際にはあなたが望んでいるものではないと考える人々と一緒です. 特に、インスタンスは、渡す場所やコードがインスタンスに対して行う処理によっては、予想よりも長く存続する可能性があるため、常にあると思うインスタンスがあるとは限りません。(これの一部は暗黙的に発生することさえあります。) 一般に、これについて明示する方が適切です。クラスのさまざまなインスタンスをコード (およびライブラリ) 全体でランダム変数に格納するよりも、それらのプライマリ リポジトリをリストにします。または他のコンテナにアクセスし、そこからそれらにアクセスします。次に、それらを簡単に反復処理して、必要な属性を取得できます。ただし、このようなユースケースがあるかもしれませんし、コード化することも可能です。