繁体   English   中英

如何在 Python 中继承和扩展类属性?

[英]How to inherit and extend class attributes in Python?

我在网上做了很多研究,但我没有找到用子类中的新值扩展“类”属性字典的正确方法。 大多数文档都在方法内部扩展属性。

我试过dictionary.update()但它不起作用。

这是我的例子:

class Super(object):
    dictionary = {'one':1, 'two':2}

    def __init__(self, var):
        self.var = var

    def supermethod(self):
        pass

我将其扩展为:

class Subclass(Super):
    dictionary.update({"zero":0})

    def __init__(self, var):
        super(Subclass, self).__init__(var)
        self.var = var

    def submethod(self):
        pass

如果我覆盖字典 - 它工作正常。 但是如果我尝试扩展,它会给我:

AttributeError: 'Subclass' 对象没有属性 'dictionary'

在 Python 中, class是一个可执行语句。 当解释器找到class语句时,首先执行class语句块中的所有代码(在一个特殊的命名空间中),然后使用该块中定义的所有名称来构建class对象(Python类是对象),最后类名绑定到当前作用域中的类对象。

IOW,在 class 语句的块中, class对象尚不存在,因此无法引用它,既不能显式(通过类名)也不能隐式(Python 无论如何都过于显式而不是隐式)。

OTHO,父类对象显然在这一点上确实存在(否则您无法从它继承),因此您可以显式引用它:

class Parent(object):
   attr = something()


class Child(Parent):
   attr = Parent.attr
   # do something with Parent.attr

请注意,在 class 语句块(此处为attr )中定义的attr是“类属性”,即class对象的 IOW 属性,因此在实例之间共享。 当这个属性是一个可变对象时,从一个实例改变它会影响所有实例。

还要记住 Python从不隐式复制任何东西,所以下面的代码:

class Parent(object):
   attr = {"foo": "bar"}


class Child(Parent):
   attr = Parent.attr
   attr["baaz"] = "quux"
   # or attr.update(baaz="quux") etc

将更新Parent.attr

子类永远不会将其超类的属性作为其属性,无论是否为方法。

class Subclass(Super):
  dictionary = Super.dictionary
  dictionary.update({zero:0})

子类确实将其超类的属性作为其属性。 您不能使用directionay.update({"zero":0})因为当时class Subclass还不存在。 如果你不做 line1 & line2,你仍然可以看到 line4 打印{'one':1, 'two':2}证明它。

但是如果你做 line1 & line2,你必须添加copy() ,否则,你会看到 line3 & line4 都变成{'zero': 0, 'two': 2, 'one': 1} ,这意味着你想要扩展子类中的参数,但同时修改超类中的参数,这是不合理的。

所以下面的代码只会输出:

{'二':2,'一':1}

{'零':0,'二':2,'一':1}

我认为满足您的要求。

class Super(object):
    dictionary = {'one':1, 'two':2}

    def __init__(self, var):
        self.var = var

    def supermethod(self):
        pass

class Subclass(Super):
    dictionary = Super.dictionary.copy() # line1
    dictionary.update({"zero":0}) # line2

    def __init__(self, var):
        super(Subclass, self).__init__(var)
        self.var = var

    def submethod(self):
        pass

print(Super.dictionary) # line3
print(Subclass.dictionary) # line4

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM