在Python 3中.x、 super()可以在没有参数的情况下调用:

class A(object):
    def x(self):
         print("Hey now")

class B(A):
    def x(self):
        super().x()
>>> B().x()
Hey now

为了实现这一点,执行了一些编译时魔法,其结果之一是以下代码(将super重新绑定到super_)失败:

super_ = super

class A(object):
    def x(self):
        print("No flipping")

class B(A):
    def x(self):
        super_().x()
>>> B().x()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in x
RuntimeError: super(): __class__ cell not found

为什么没有编译器的帮助,super()无法在运行时解析超类?在实际情况下,这种行为或其潜在原因是否会伤害一个粗心的程序员?

... 另外,作为一个附带问题:Python中是否还有其他函数、方法等的例子,可以通过将它们重新绑定到不同的名称来打破它们?

推荐答案

添加了新的magic super()行为,以避免违反D.R.Y.(不要重复自己)原则,请参见PEP 3135.必须通过将类引用为全局类来显式命名该类,也容易出现与super()本身相同的重新绑定问题:

class Foo(Bar):
    def baz(self):
        return super(Foo, self).baz() + 42

Spam = Foo
Foo = something_else()

Spam().baz()  # liable to blow up

这同样适用于使用类decorator ,其中decorator 返回一个新对象,该对象将重新绑定类名:

@class_decorator_returning_new_class
class Foo(Bar):
    def baz(self):
        # Now `Foo` is a *different class*
        return super(Foo, self).baz() + 42

magic super() __class__单元通过允许您访问原始类对象,很好地回避了这些问题.

政治公众人物由initially envisioned super becoming a keyword岁的Guido发起,他提出了用一个单元格查找当前was also his类的 idea .当然,将其作为关键词的 idea 是first draft of the PEP的一部分.

然而,事实上,当时stepped away from the keyword idea as 'too magical'岁的Guido本人提出了当前的实施方案.他说:

我的补丁使用了一个中间解决方案:它假设你需要__class__

所以,最终,是Guido自己宣称使用super关键字感觉不对劲,提供一个神奇的__class__单元是一个可以接受的折衷方案.

我同意实现的神奇、隐含的行为有些令人惊讶,但super()是语言中应用最错误的函数之一.只要看看互联网上发现的所有误用的super(type(self), self)super(self.__class__, self)次调用;如果有任何代码是从派生类you'd end up with an infinite recursion exception调用的.至少简化的super()调用,没有参数,避免了that问题.

至于更名的super_人;只要在方法as well中引用__class__,它就会再次起作用.如果引用方法中的super or __class__名称,则会创建单元格:

>>> super_ = super
>>> class A(object):
...     def x(self):
...         print("No flipping")
... 
>>> class B(A):
...     def x(self):
...         __class__  # just referencing it is enough
...         super_().x()
... 
>>> B().x()
No flipping

Python-3.x相关问答推荐

将两列的乘积连续添加到一列的累积和中

与 pandas 0.22 相比,pandas 2.0.3 中的 df.replace() 会抛出 ValueError 错误

在python内的powershell中转义$_

如何根据索引子列表对元素列表进行分组或批处理?

从 https://www.niftytrader.in/stock-options-chart/sbin 提取 SBIN 股票最大痛苦值的 Python 代码不起作用 - 我错过了什么?

生成具有偶数个 0 和 1 的给定长度的所有二进制数

从列表的元素和python中的多个多索引数据帧执行方程

我正在使用 python 线程,当查询 mysql 时,代码似乎在运行并保持在无限循环中,没有返回任何错误

切片的Python复杂性与元组的星号相结合

来自嵌套字典的完整地址

pymongo 失败并出现错误未定义

django rest框架中的save()、create()和update()有什么区别?

Python:如何在三个列表中找到共同值

如何使我的课程在 Python 中非常可打印?

TensorFlow:dataset.train.next_batch 是如何定义的?

为什么我在 Python 中收到错误消息无法导入名称 NoneType?

如何用pymongo连接远程mongodb

如何使用 d.items() 更改 for 循环中的所有字典键?

如何强制 Sphinx 使用 Python 3.x 解释器

在 Meta 中创建具有动态模型的通用序列化程序