在大多数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
答案 0 :(得分:3)
这完全取决于用例。考虑一下。
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
如果您在super()
内设置self.name
之前调用Bar.__init__
,则需要AttributeError
,因为尚未设置所需的名称。
答案 1 :(得分:1)
将它放在init方法的底部是不好的形式?
你问错了问题。无论是否不好,都有一些有效的用例,用于将超类初始化移动到子类的构造函数的底部。调用超类的构造函数完全取决于超类构造函数的实现。
例如,假设您有一个超类。构造超类时,您希望根据子类的属性为属性指定一个值:
class Superclass:
def __init__(self):
if self.subclass_attr == True:
self.attr = 1
else:
self.attr = 2
从上面可以看出,我们希望子类具有属性subclass_attr
。那么这是什么意思? 我们无法初始化Supperclass
,直到我们为子类subclass_attr
属性。
因此,我们必须推迟调用超类的构造函数,直到我们初始化subclass_attr
。换句话说,对super
的调用必须放在子类构造函数的底部:
class Subclass(Superclass):
def __init__(self):
self.subclass_attr = True
super(Superclass, self).__init__()
最后,选择放置super
的位置不应该基于某种风格,而应该基于什么样的风格。