Running this code:
import weakref
class A(object):
    _instances = []
    def __init__(self):
        self._instances.append(weakref.ref(self))
    @property
    @classmethod
    def instances(cls):
        for inst_ref in cls._instances:
            inst = inst_ref()
            if inst is not None:
                yield inst
foo = A()
bar = A()
for inst in A.instances:
    print inst
I get this error:
Traceback (most recent call last):
  File "test.py", line 18, in <module>
    for inst in A.instances:
TypeError: 'property' object is not iterable
I can't figure out how having a class method behave like a property (no parentheses).
Here is one way to use descriptors with a class:
import weakref
class classproperty(object):
    def __init__(self, fget):
        self.fget = fget
    def __get__(self, owner_self, owner_cls):
        return self.fget(owner_cls)
class A(object):
    _instances = []
    def __init__(self):
        self._instances.append(weakref.ref(self))
    @classproperty
    def instances(cls):
        for inst_ref in cls._instances:
            inst = inst_ref()
            if inst is not None:
                yield inst
foo = A()
bar = A()
for inst in A.instances:
    print inst
References:
Properties always apply to instances, not classes.
The way to do this would be to define a metaclass that defines the property on its own instance method, since a class is an instance of its metaclass:
class AMeta(type):
    def __init__(self,name,bases,dict):
        self._instances = []
    @property
    def instances(self):
        for inst_ref in self._instances:
             inst = inst_ref()
             if inst is not None:
                 yield inst
class A(object):
     __metaclass__ = AMeta
     def __init__(self):
         self._instances.append(weakref.ref(self))
This now works as expected:
>>> foo=A()
>>> bar = A()
>>> for inst in A.instances:
...     print inst
<__main__.A object at 0x1065d7290>
<__main__.A object at 0x1065d7990>
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With