Python3可变静态类成员

时间:2018-03-12 16:26:55

标签: python-3.x

我需要使用静态类函数变量,所有可用类都将从具有所有常用方法和变量的单个父类继承。

目前的行为是父类中定义的类变量不会对每个孩子造成干扰,并且在所有孩子之间共享(需要它作为discreed变量)

class Parent(object):
    cls_var = list()

    @classmethod
    def cls_mthd(cls, a):
        cls.cls_var.append(a)

class ChildA(Parent):
    pass

ChildA.cls_mthd('A')

class ChildB(Parent):
    pass

ChildB.cls_mthd('B')

print(Parent.cls_var)
print(ChildA.cls_var)
print(ChildB.cls_var)

输出

['A', 'B']
['A', 'B']
['A', 'B']

我设法获得所需行为的解决方法就是这样,但我不认为这种黑客行为是最好的方式

class Parent(object):
    cls_var = dict()

    @classmethod
    def cls_mthd(cls, a):
        if cls.__name__ not in cls.cls_var:
            cls.cls_var[cls.__name__] = list()
        cls.cls_var[cls.__name__].append(a)

    @classmethod
    def tst(cls):
        return cls.cls_var[cls.__name__] if cls.__name__ in cls.cls_var else None

class ChildA(Parent):
    pass

ChildA.cls_mthd('A')

class ChildB(Parent):
    pass

ChildB.cls_mthd('B')

print(Parent.tst())
print(ChildA.tst())
print(ChildB.tst())

输出

None
['A']
['B']

1 个答案:

答案 0 :(得分:1)

为了拥有可变的静态类成员,您可以使用metaclass

class MutableClassVarMeta(type):
    def __new__(meta, name, bases, namespace, **kwds):
        cls = super().__new__(meta, name, bases, namespace, **kwds)
        cls.cls_var = []
        return cls

class Parent(metaclass=MutableClassVarMeta):
    @classmethod
    def cls_mthd(cls, a):
        cls.cls_var.append(a)

class ChildA(Parent):
    pass

class ChildB(Parent):
    pass

ChildA.cls_mthd('A')
ChildB.cls_mthd('B')

print(Parent.cls_var)  # []
print(ChildA.cls_var)  # ['A']
print(ChildB.cls_var)  # ['B']

(或者您真的希望NoneParent.cls_var吗?)

我承认它比你的解决方法更冗长,但(对我来说)它看起来更加pythonic ......

<强>更新

正如Blckknght所指出的,元类可以(也可能应该)看起来更简单:

class MutableClassVarMeta(type):
    def __init__(cls, name, bases, attrs):
        cls.cls_var = []