【发布时间】:2018-12-13 07:54:41
【问题描述】:
我是 Python 初学者,使用 Lutz 的书了解 Python 中的 OOPS。这个问题可能是基本的,但我会很感激任何帮助。我研究了 SO 并找到了关于“如何”的答案,但没有找到“为什么”的答案。
据我从书中了解到,如果Sub 继承Super,则无需调用超类'(Super's)__init__() 方法。
示例:
class Super:
def __init__(self,name):
self.name=name
print("Name is:",name)
class Sub(Super):
pass
a = Sub("Harry")
a.name
以上代码确实将属性name 分配给对象a。它还按预期打印name。
但是,如果我将代码修改为:
class Super:
def __init__(self,name):
print("Inside Super __init__")
self.name=name
print("Name is:",name)
class Sub(Super):
def __init__(self,name):
Super(name) #Call __init__ directly
a = Sub("Harry")
a.name
上面的代码不能正常工作。好的,我的意思是虽然Super.__init__() 确实被调用(从打印语句中可以看出),但a 没有附加属性。当我运行a.name 时,我得到一个错误,AttributeError: 'Sub' object has no attribute 'name'
我在 SO 上研究了这个主题,并在 Chain-calling parent constructors in python 和 Why aren't superclass __init__ methods automatically invoked? 上找到了解决方法
这两个线程讨论了如何修复它,但没有提供原因。
问题:为什么我需要使用Super.__init__(self, name) 或super(Sub, self).__init__(name) 来调用Super 的__init__,而不是直接调用Super(name)?
在Super.__init__(self, name) 和Super(name) 中,我们看到Super 的__init__() 被调用(从打印语句中可以看出),但仅在Super.__init__(self, name) 中,我们看到该属性附加到Sub 类。
Super(name) 不会自动将self(子)对象传递给Super?现在,你可能会问,我怎么知道self 是自动通过的?如果我将Super(name) 修改为Super(self,name),我会收到TypeError: __init__() takes 2 positional arguments but 3 were given 的错误消息。据我从书中了解到,self 是自动通过的。所以,实际上,我们最终通过了self 两次。
我不知道为什么Super(name) 没有将name 属性附加到Sub,即使Super.__init__() 已运行。我会很感激任何帮助。
作为参考,这是基于我对 SO 的研究的代码的工作版本:
class Super:
def __init__(self,name):
print("Inside __init__")
self.name=name
print("Name is:",name)
class Sub(Super):
def __init__(self,name):
#Super.__init__(self, name) #One way to fix this
super(Sub, self).__init__(name) #Another way to fix this
a = Sub("Harry")
a.name
PS:我在 Anaconda Distribution 下使用Python-3.6.5。
【问题讨论】:
-
Super(name)创建一个new实例Super立即被丢弃。您需要在特定实例(self)上调用__init__(),首选super(),您不再需要将参数传递给super(),例如super().__init__(name)就足够了。 -
在您的类
Sub中,您正在初始化父类的新实例,这不是您想要做的。Subclass想要初始化父类的所有属性/方法(继承)(请参阅 abarnert 的答案以了解操作方法)。因为你没有初始化父类的类属性,所以你没有给你的子实例(你称之为a)属性name。而您正在尝试访问一个不存在的属性,这就是引发错误的原因。
标签: python python-3.x inheritance