为什么 Python 3.x 的 super() 可以施展魔法
在 Python 3.x 中,无需调用 super() 函数即可论据。这允许简化和改进的超类调用,如下所示:
<code class="python">class A(object): def x(self): print("Hey now") class B(A): def x(self): super().x() B().x() # Outputs: "Hey now"</code>
此功能是通过编译时魔术实现的,这确保 super() 在运行时可以访问正确的超类。然而,当 super() 反弹到不同的名称时,这种行为也可能导致意外错误,如下所示:
<code class="python">super_ = super class A(object): def x(self): print("No flipping") class B(A): def x(self): super_().x() B().x() # Raises: RuntimeError: super(): __class__ cell not found</code>
揭开 super() 的内部工作原理
super() 背后的魔力在于编译时 class 单元格,该单元格是在方法中引用 super 或 class 时创建的。此单元格为 super() 提供了对原始类对象的访问,即使类名已被重新绑定。
引入此 class 单元格机制是为了防止因显式命名类而导致的错误当调用 super() 或使用返回新类对象的类装饰器时。它还避免了 super() 的误用,例如使用 super(type(self), self) 或 super(self.__class__, self) 进行调用,从而导致无限递归。
实用应用程序和陷阱
虽然 class 单元格增加了便利性,但在某些情况下也可能导致意外行为。例如,如果 super() 被反弹到不同的名称(例如,前面所示的 super_)并且该方法未显式引用 class,则 super() 调用将失败。
了解底层机制可能有益的另一个例子是使用类装饰器。如果装饰器返回一个新的类对象,class单元格将继续引用原始类,确保正确的超类调用。
值得注意的是,重新绑定其他函数、方法或Python 中的类也可能导致意外行为。然而,super() 是一个特别值得注意的例子,因为它在面向对象编程中发挥着核心作用。
以上是为什么 Python 3.x 的 super() 具有这种'神奇”行为,什么时候会导致错误?的详细内容。更多信息请关注PHP中文网其他相关文章!