Python 如何自动向某些子类添加类变量

Python 如何自动向某些子类添加类变量,python,python-2.7,Python,Python 2.7,这将创建所有实例并将它们放入A.\u all。我想要的是将C的实例放在C.\u all(对于C也是如此) 我可以这样定义B和C: class A(object): _all = set() def __new__(cls): obj = super(A,cls).__new__(cls) cls._all.add(obj) return obj class B(A): pass class C(A): pass

这将创建所有实例并将它们放入
A.\u all
。我想要的是将
C
的实例放在
C.\u all
(对于C也是如此)

我可以这样定义
B
C

class A(object):
    _all = set()

    def __new__(cls):
        obj = super(A,cls).__new__(cls)
        cls._all.add(obj)
        return obj

class B(A):
    pass

class C(A):
    pass

b = B()
c = C()
那就行了。然而,这感觉像是重复代码,如果我在下一步子类
A
时忘记添加
\u all
,或者拼写错误
\u all
,我很可能会很难调试错误


如何做好这一点?

\u all
设置为
None
,如果仍然
None
,则在
\u new\u
中创建您的集合,为每个类提供自己的副本:

class B(A):
    _all = set()

class C(A):
    _all = set()

这里有一个元类:

class A(object):
    _all = None

    def __new__(cls):
        obj = super(A,cls).__new__(cls)
        if cls._all is None:
            cls._all = set()
        cls._all.add(cls)
        return obj
在Python 3中,
A
的定义必须是:

class make_all_meta(type):
   def __init__(cls, name, bases, dic):
       type.__init__(cls, name, bases, dic)
       cls._all = set()

class A(object):
    __metaclass__ = make_all_meta

这正是我要建议的方法。你也可以用一个元类来做,虽然这稍微复杂一点。元类的方式感觉更“正确”,但我担心以后会更加复杂。此外,我不能做像
len(B._all)==0这样的事情,因为至少要实例化一个
B
B._allis None
我已经发布了一个带有元类的答案。没错,它确实简化了
len()
问题。当然,您也可以首先将
\u all
定义为空元组或其他内容,而不是
None
。此解决方案假定在所有其他子类的第一个实例之前不会创建任何实例。我建议至少做
断言cls不是
\uuuuu new\uuuuu
中的一个
。它不应该是
cls.\u all.add(obj)
而不是
cls.\u all.add(cls)
class A(metaclass=make_all_meta):
    pass