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

Gin*_*ger 7 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
Run Code Online (Sandbox Code Playgroud)

Ric*_*ann 5

这完全取决于用例。考虑一下。

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.nameBar.__init__你会得到一个AttributeError,因为所需的名字尚未确定。


Chr*_*ean 5

将它放在 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不应该基于某种风格,而应该基于必要的东西。

  • 正确且详细的答案。请注意,给出的示例说明了一个非常糟糕的设计:理想情况下,超类永远不应该处理仅存在于其子类上的属性。 (3认同)