正在初始化超类Python3



我试图了解在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")

通常,如果在子类中重写__init__,则应仅调用超级__init__方法。如果扩展超类,这是必要的。但是,如果要覆盖整个__init__,也可以省略超级调用。

示例:

您有一个类A,它有一个属性value1。现在你需要第二个属性,所以你用B来划分A的子类,并覆盖你调用超类(A(的__init__,所以A可以设置value1,而在B中你不能设置value2
但现在您需要C中的一些其他属性,但需要与A中相同的方法。因此,您可以完全覆盖__init__,并省略对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'

您可以看到C没有用value1初始化,因为C没有调用A__init__

最新更新