运行此代码:
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
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
Traceback (most recent call last):
File "test.py", line 18, in <module>
for inst in A.instances:
TypeError: 'property' object is not iterable
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚类方法的行为如何像属性(没有括号).
以下是使用描述符和类的一种方法:
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
Run Code Online (Sandbox Code Playgroud)
参考文献:
属性始终适用于实例,而不适用于类。
这样做的方法是定义一个元类,该元类通过自己的实例方法定义属性,因为一个类是其元类的实例:
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))
Run Code Online (Sandbox Code Playgroud)
现在可以正常工作了:
>>> foo=A()
>>> bar = A()
>>> for inst in A.instances:
... print inst
<__main__.A object at 0x1065d7290>
<__main__.A object at 0x1065d7990>
Run Code Online (Sandbox Code Playgroud)