正在初始化超类 Python3
Initializing superclasses Python3
我想了解在 python 中使用继承时何时初始化超级 class。最初我认为只需声明一个 class 继承自超级 class,例如。 class my_class(superclass):, 将使 superclass 的所有属性和方法对 subclass 可用。这对于来自 Java 的人来说是有意义的。然后我读到 Python 强制我们初始化 superclasses,然后才能在我们的 subclass 中实现它们,或者使用 superclass. init() 或 super().init()。然后我遇到了这段代码,其中我没有初始化父级的 class,但是 Python 让我可以在没有初始化父级的情况下访问 superclass 的 self.queue 属性class。我阅读了 Python 文档,有时我认为我知道它们的意思,而其他一些我不知道。任何人都可以向我解释一下我们什么时候必须在我们的 subclasses 中初始化 superclasses 吗?
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")
一般来说,如果您在子class 中覆盖__init__
,您应该只调用超级__init__
方法。如果您扩展 superclass,这是必需的。但是如果你想覆盖整个__init__
,你也可以省略super的调用。
示例:
您 class A
具有一个属性 value1
。
现在你需要第二个属性,所以你用 B
subclass A
并覆盖你调用 super class 的 __init__
(A
), 所以 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__
.
我想了解在 python 中使用继承时何时初始化超级 class。最初我认为只需声明一个 class 继承自超级 class,例如。 class my_class(superclass):, 将使 superclass 的所有属性和方法对 subclass 可用。这对于来自 Java 的人来说是有意义的。然后我读到 Python 强制我们初始化 superclasses,然后才能在我们的 subclass 中实现它们,或者使用 superclass. init() 或 super().init()。然后我遇到了这段代码,其中我没有初始化父级的 class,但是 Python 让我可以在没有初始化父级的情况下访问 superclass 的 self.queue 属性class。我阅读了 Python 文档,有时我认为我知道它们的意思,而其他一些我不知道。任何人都可以向我解释一下我们什么时候必须在我们的 subclasses 中初始化 superclasses 吗?
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")
一般来说,如果您在子class 中覆盖__init__
,您应该只调用超级__init__
方法。如果您扩展 superclass,这是必需的。但是如果你想覆盖整个__init__
,你也可以省略super的调用。
示例:
您 class A
具有一个属性 value1
。
现在你需要第二个属性,所以你用 B
subclass A
并覆盖你调用 super class 的 __init__
(A
), 所以 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__
.