Python 3.x 初始化超类Python3

Python 3.x 初始化超类Python3,python-3.x,inheritance,initialization,Python 3.x,Inheritance,Initialization,我试图理解在python中使用继承时何时初始化超类。最初我认为,只要声明一个继承自超类的类,例如class my_class(superclass):,就可以将超类的所有属性和方法提供给子类。这对来自Java的人来说是有意义的。然后我读到Python迫使我们在子类中实现超类之前初始化它们,或者使用超类。init()或者super()。init()。然后我遇到了这段代码,我没有初始化父类,但是Python允许我在没有初始化父类的情况下从超类访问self.queue属性。我阅读了Python文档,有

我试图理解在python中使用继承时何时初始化超类。最初我认为,只要声明一个继承自超类的类,例如class my_class(superclass):,就可以将超类的所有属性和方法提供给子类。这对来自Java的人来说是有意义的。然后我读到Python迫使我们在子类中实现超类之前初始化它们,或者使用超类。init()或者super()。init()。然后我遇到了这段代码,我没有初始化父类,但是Python允许我在没有初始化父类的情况下从超类访问self.queue属性。我阅读了Python文档,有时我想我知道它们的意思,而有些我不知道。有人能告诉我什么时候我们必须在我们的子类中初始化超类吗

class QueueError(IndexError):
pass

class Queue:
    def __init__(self):
       self.queue = []
    def put(self,elem):
       self.queue.insert(0,elem)
    def get(self):
        if len(self.queue) > 0:
            elem = self.queue[-1]
            del self.queue[-1]
            return elem
        else:
            raise QueueError

    class SuperQueue(Queue):
    def isempty(self):
        if not self.queue:
            return True
        else:
            return False

que = SuperQueue()
que.put(1)
que.put("dog")
que.put(False)
for i in range(4):
    if not que.isempty():
        print(que.get())
    else:
        print("Queue empty")

通常,如果在子类中重写
\uuuuu init\uuu
,则应仅调用super
\uuuuuuu init\uu
方法。如果扩展超类,这是必需的。但是如果您想覆盖整个
\uuuu init\uuuu
,您也可以省略超级调用

示例:

您有一个类
A
,它有一个属性
value1
。 现在您需要第二个属性,这样您就可以用
B
a
进行子类化,并覆盖调用超类(
a
)的
,这样
a
就可以设置
value1
,而在
B
中就不能设置
value2

但是现在您需要
C
中的一些其他属性,但是需要与
A
中相同的方法。因此,您可以完全覆盖
\uuuu init\uuuu
并省略对
A
的超级调用

class A:
    def __init__(self, value1):
        print("Initialize A")
        self.value1 = value1


class B(A):
    def __init__(self, value1, value2):
        super().__init__(value1)
        print("Initialize B")
        self.value2 = value2


class C(A):
    def __init__(self, value3):
        print("Initialize C")
        self.value3 = value3


a = A("foo")
b = B("foo", "bar")
c = C("baz")

print(a.value1)
print(b.value1, b.value2)
print(c.value3)
print(c.value1)
输出

$ python main.py
Initialize A
Initialize A
Initialize B
Initialize C
foo
foo bar
baz
Traceback (most recent call last):
  File "main.py", line 27, in <module>
    print(c.value1)
AttributeError: 'C' object has no attribute 'value1'
$python main.py
初始化
初始化
初始化B
初始化C
福
富吧
巴兹
回溯(最近一次呼叫最后一次):
文件“main.py”,第27行,在
打印(c.1)
AttributeError:“C”对象没有属性“value1”

你可以看到
C
没有用
value1
初始化,因为
C
没有调用
A
\uuuu init\uuu

换句话说,我们可以说子类自动继承了超类的所有特征。但是如果子类试图访问超类traits,它将生成AttributeError异常,前提是我们重写了超类init。现在我看到了super()。\uuuu init\uuuuu()正在做什么,它基本上是让子类访问在超类init中定义的超类的特性,当这个特性在子类中被重写时。非常感谢。