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

时间:2018-07-13 11:54:39

标签: python oop dictionary inheritance attributes

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

我尝试了 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:“子类”对象没有属性“字典”

谢谢

3 个答案:

答案 0 :(得分:4)

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

IOW,在类语句的块中,class对象尚不存在,因此无法显式地(通过类名)或隐式地引用它(无论如何,Python都显式地超过了隐式) )。

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

class

请注意,在类语句块(此处为class Parent(object): attr = something() class Child(Parent): attr = Parent.attr # do something with Parent.attr 中定义的属性是“类属性”,attr对象的IOW属性,因此在实例之间共享。如果此属性是可变对象,则从一个实例对其进行突变将影响所有实例。

还要记住,Python 从不隐式复制任何内容,因此下面的代码:

class

将更新class Parent(object): attr = {"foo": "bar"} class Child(Parent): attr = Parent.attr attr["baaz"] = "quux" # or attr.update(baaz="quux") etc

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

子类确实具有其超类的属性作为其属性。 您不能使用directionay.update({"zero":0}),因为当时class Subclass仍然不存在。 如果您不执行第1行和第2行,则仍然可以看到第4行打印{'one':1, 'two':2}来证明这一点。

但是,如果执行第1行和第2行,则必须添加copy(),否则,您将看到第3行和第4行都变为{'zero': 0, 'two': 2, 'one': 1},这意味着您想扩展子类中的参数,但同时修改超类中的参数,这是不合理的。

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

  

{'two':2,2,'one':1}

     

{'零':0,'两个':2,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