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

时间:2009-12-24 07:41:48

标签: python language-design

在python 2.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).__init__()。从技术上讲,您可以从对象本身获取对象的类型,因此当前策略super(ClassType, self).__init__()是多余的。我假设与旧式类的兼容性问题,或多重继承,但我想听听你的观点。
  • 另一方面,为什么python 3会接受(见Understanding Python super() with __init__() methodssuper().__init__()?我在这看到了一种魔法,违背了显性比隐含的禅更好。我会看到更合适的self.super().__init__()

2 个答案:

答案 0 :(得分:6)

合作多重继承方案中

super(ClassType, self).__init__() 多余 - ClassType不一定是self的类型,而是您想要的类与__init__进行合作调用。

在类层次结构C inherits B inherits A中,在C.__init__中,您希望从C's角度调用超类'init,并调用B.__init__;然后在B.__init__中你必须将类类型B传递给super - 因为你想要解析B的调用超类(或者更确切地说,是C类B之后的mro中的下一个)。 p>

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__()

如果您现在实例化c = C(),您会发现类类型不是多余的 - super(self).__init__()内的B.__init__不会真正起作用!你所做的是你手动指定调用super的方法在哪个类中(这是通过指向方法类的隐藏变量在Python 3的super中解决的)。

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

答案 1 :(得分:3)

我无法提供具体的答案,但您是否阅读了超级关键字周围的PEP?我做了一个快速的谷歌搜索,它提出了PEP 367和PEP 3135。

http://www.python.org/dev/peps/pep-0367/

http://www.python.org/dev/peps/pep-3135/#numbering-note

与我所知道的任何其他语言不同,大多数时候你可以在PEP中找到Python怪癖的答案以及明确的理性和立场声明。

更新

通过阅读3135,Python Mailing中的相关电子邮件和语言参考,它有点理由为什么它是Python 2与Python 3的对比。

http://docs.python.org/library/functions.html?highlight=super#super

我认为super实现为显式/冗余只是为了安全起见并尽可能简化逻辑(没有糖或深度逻辑来找到父级)。由于super是一个内置函数,它必须从所提供的内容中推断出正确的返回,而不会为Python对象的结构添加更复杂的内容。

PEP 3135改变了一切,因为它呈现并赢得了DRY'er超级方法的争论。