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

Cla*_*diu 2 python oop inheritance attributes dictionary

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

我尝试了dictionary.update()但不起作用。

这是我的示例:

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

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

    def supermethod(self):
        pass
Run Code Online (Sandbox Code Playgroud)

我扩展到:

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

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

    def submethod(self):
        pass
Run Code Online (Sandbox Code Playgroud)

如果我重写字典-可以正常工作。但是,如果我尝试扩展,它会给我AttributeError:'Subclass'对象没有属性'dictionary'

谢谢

bru*_*ers 6

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

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

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

class Parent(object):
   attr = something()


class Child(Parent):
   attr = Parent.attr
   # do something with Parent.attr
Run Code Online (Sandbox Code Playgroud)

注意,在class语句块(此处为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
Run Code Online (Sandbox Code Playgroud)

将会更新Parent.attr

  • 谢谢。您解释的方式是:`> 另请记住,Python 永远不会隐式复制任何内容,因此下面的代码:> 将更新 Parent.attr。` 消除了我心中的很多疑虑! (2认同)

Ign*_*ams 5

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

class Subclass(Super):
  dictionary = Super.dictionary
  dictionary.update({zero:0})
Run Code Online (Sandbox Code Playgroud)

  • 子类确实有其超类的属性(好吧,更准确地说,可以通过子类访问超类属性),但不在 `class` 语句块中。 (7认同)

atl*_*ine 5

子类确实具有其超类的属性作为其属性。您不能使用,directionay.update({"zero":0})因为当时class Subclass还不存在。如果您不执行第 1 行和第 2 行,您仍然可以看到第 4 行打印{'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
Run Code Online (Sandbox Code Playgroud)