为什么python super不只接受实例?

为什么python super不只接受实例?,python,language-design,Python,Language Design,在Python2.x中,super接受以下情况 class super(object) | super(type) -> unbound super object | super(type, obj) -> bound super object; requires isinstance(obj, type) | super(type, type2) -> bound super object; requires issubclass(type2, type) |

在Python2.x中,super接受以下情况

class super(object)
 |  super(type) -> unbound super object
 |  super(type, obj) -> bound super object; requires isinstance(obj, type)
 |  super(type, type2) -> bound super object; requires issubclass(type2, type)
 |  Typical use to call a cooperative superclass method:
在我看来,super是一个类,它包装类型和(最终)实例以解析类的超类

有几件事让我很困惑:

  • 为什么也没有
    super(instance)
    ,典型用法是
    super(self)。\uuuu init\uuuu()
    。从技术上讲,您可以从对象本身获取对象的类型,因此当前的策略
    super(ClassType,self)。\uuu init\uuu()
    有点多余。我假设与旧式类或多重继承存在兼容性问题,但我想听听您的观点
  • 另一方面,为什么python 3会接受(请参阅)
    super()?我从中看到了一种魔力,违反显式的禅宗比隐式的禅宗好。我会看到更合适的
    self.super()

我无法提供具体的答案,但您是否阅读了有关super关键字的政治公众人物介绍?我在谷歌上快速搜索了一下,找到了PEP367和PEP3135

与我所知道的任何其他语言不同,大多数情况下,您可以在PEP中找到Python怪癖的答案,以及清晰的rational和position语句

更新:

通读了3135,Python邮件中的相关电子邮件,以及语言参考,这就有点道理了,为什么Python2和Python3是这样的

我认为super的实现是显式的/冗余的,只是为了安全起见,并尽可能简单地保持所涉及的逻辑(没有糖或深层逻辑来找到父对象)。由于super是一个内置函数,因此它必须从所提供的内容推断正确的返回,而不会给Python对象的结构增加更多的复杂性

PEP 3135改变了一切,因为它提出并赢得了一个对超级(ClassType,self)更为枯燥的方法的争论。

super(ClassType,self)。\uuuu init\uuuu()
在合作多重继承方案中并不冗余--
ClassType
不一定是
self
的类型,但是要从中执行对
\uuuu init\uuuu
的协作调用的类

在类层次结构
C继承B继承A
,在
C.\uuuu init\uuuu
中,您想从
C的
透视图调用超类'init',然后调用
B.\uu init\uuuu
;然后在
B.\uuuu init\uuuu
中,您必须将类类型
B
传递给super——因为您想要解析调用B的超类(或者更确切地说,是类C的B之后的mro中的下一个超类)

如果您现在实例化
c=c()
,您会看到类类型不是冗余的--
super(self)。\uuuuu init\uuuuu()
内部
B.\uuuu init\uuuuuu
不会真正工作!您要做的是手动指定调用super的方法在哪个类中(在Python3的super中,这是通过一个指向该方法的类的隐藏变量来解决的)

超级继承和多重继承示例的两个链接:


我同意,但我正试图找到问题的答案,同时增加stackoverflow信息。@Stefano在我发表原始帖子后,我立即开始思考同样的问题。我猜你指的是B类(A)和C类(B):然而,你是对的。它永远无法从B调用A.uuu init_uuu(),因为在方法B中,self的类型是C,它的直接super是B,而不是A。因此,B.uu init_uuu()将再次被调用。啊,关于输入错误,你是对的,谢谢!在多重继承方案中,这变得更加复杂,我想我可以找到一个关于它的链接。@kaizer.se我明白你的意思,但是有没有一个实例,当super()的类型参数不是定义方法的类时?例如,如果B有一个init,那么B.。\uuuuu init\uuuuu的主体是否会包含super(foo,self)?
class A (object):
  def __init__(self):
    pass

class B (A):
  def __init__(self):
    super(B, self).__init__()

class C (B):
  def __init__(self):
    super(C, self).__init__()