如何使子类之间不共享的类变量



我需要使用变量,这些变量在类的实例之间共享。所以,类变量似乎符合要求。但是这些类变量在子类之间是共享的,这是需要避免的。

问题来了:

class Parent(object):
    a=[]
class Child(Parent):
    pass
print(Child.a is Parent.a) # => True # Need to avoid this

我是这样解决的:

  1. 可以通过将父类变量重新声明为Child来影子父类变量,但仍然可以删除Child的"a"变量,当Child。a再次指向父方。一个。

    class Parent(object):
        a=[]
    class Child(Parent):
        a=[] # Works, but delete-able.
    print(Child.a is Parent.a) # => False # Works
    del Child.a
    print(Child.a is Parent.a) # => True # Breaks again
    
  2. 与前文相同,但通过元类添加了"a",这样更好。

    class meta(type):
        def __new__(cls, name, base, clsdict):
                temp_class = type.__new__(cls, name, base, clsdict)
                temp_class.a=[]
                return temp_class
    class Parent(object):
        __metaclass__=meta
    class Child(Parent):
        pass
    print(Child.a is Parent.a) # => False # Works
    del Child.a
    print(Child.a is Parent.a) # => True # Breaks again
    

但是它们都没有解决"可能删除Child的类变量"的问题。

是否有可能有一些类变量的描述符,这可以使删除不可能?如果没有,有什么好办法来解决这个问题?

要使一个类属性为该类私有,而不为子类私有,请使用"__"(两个下划线)作为前缀。这被称为"类私有成员"或"类私有引用"。

在下面的示例中,__update在Mapping类中,但不在子类中。

class Mapping:
    def __init__(self, iterable):
        self.items_list = []
        self.__update(iterable)
    def update(self, iterable):
        for item in iterable:
            self.items_list.append(item)
    __update = update   # private copy of original update() method
class MappingSubclass(Mapping):
    def update(self, keys, values):
        # provides new signature for update()
        # but does not break __init__()
        for item in zip(keys, values):
            self.items_list.append(item)

来源:Python Classes documentation

这是原始代码。注意,子类不会从父类继承__a属性。

还要注意,Child 实例对象也不继承__a属性。__a属性对于父类及其实例来说是私有的,它不被继承。

class Parent(object):
    __a = []
class Child(Parent):
    def check(self):
        print self.__a  # raises exception, __a is in Parent only, not in self
try:
    print(Child.__a is Parent.__a)
except AttributeError as exc:
    print exc
print
try:
    Child().check()
except AttributeError as exc:
    print exc

输出
type object 'Child' has no attribute '__a'
'Child' object has no attribute '_Child__a'

最新更新