super应该始终位于__init__方法的顶部,还是位于底部?

时间:2017-08-16 20:26:49

标签: python

在大多数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

2 个答案:

答案 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的位置不应该基于某种风格,而应该基于什么样的风格。

相关问题