在大多数 Python 示例中,当 super 用于调用父类的构造函数时,它出现在顶部。
将它放在init方法的底部是不好的形式吗?
在下面的示例中,super 位于 A 的构造函数的底部,但位于 B 的构造函数的顶部。
class A:
def __init__(self):
# Do some stuff
b = result_of_complex_operation()
super(A, self).__init__(b)
class B:
def __init__(self):
super(A, self).__init__(b)
# Do some stuff
Run Code Online (Sandbox Code Playgroud)
这完全取决于用例。考虑一下。
class Foo():
def __init__(self):
print(self.name)
@property
def name(self):
return self.__class__.__name__
class Bar(Foo):
def __init__(self, name):
self.name = name
super().__init__()
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
Run Code Online (Sandbox Code Playgroud)
如果您想调用super()设置之前self.name中Bar.__init__你会得到一个AttributeError,因为所需的名字尚未确定。
将它放在 init 方法的底部是一种不好的形式吗?
你问错了问题。不管它是否不好,都有有效的用例将超类初始化移动到子类构造函数的底部。对超类构造函数的调用放在哪里完全取决于超类构造函数的实现。
例如,假设您有一个超类。构造超类时,您希望根据子类的属性为属性指定特定值:
class Superclass:
def __init__(self):
if self.subclass_attr:
self.attr = 1
else:
self.attr = 2
Run Code Online (Sandbox Code Playgroud)
从上面可以看出,我们期望子类具有属性subclass_attr。那么这是什么意思?在为子类提供attribute之前,我们无法进行初始化Supperclasssubclass_attr。
因此,我们必须推迟调用超类的构造函数,直到初始化subclass_attr。换句话说,调用super必须放在子类构造函数的底部:
class Subclass(Superclass):
def __init__(self):
self.subclass_attr = True
super(Superclass, self).__init__()
Run Code Online (Sandbox Code Playgroud)
最后,选择放置位置super不应该基于某种风格,而应该基于必要的东西。