【问题标题】:Which of the 4 ways to call super() in Python 3 to use?在 Python 3 中调用 super() 的 4 种方法中的哪一种?
【发布时间】:2011-02-15 20:18:38
【问题描述】:

我想知道什么时候使用 Python 3 super() 的什么风格。

Help on class super in module builtins:

class super(object)
 |  super() -> same as super(__class__, <first argument>)
 |  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)

到目前为止,我只使用了super(),没有参数,它按预期工作(由 Java 开发人员提供)。

问题:

  • 在这种情况下,“绑定”是什么意思?
  • 绑定和未绑定的超级对象有什么区别?
  • 何时使用super(type, obj),何时使用super(type, type2)
  • 将超类命名为Mother.__init__(...) 会更好吗?

【问题讨论】:

    标签: python oop python-3.x super


    【解决方案1】:

    快速说明一下,PEP3135 New Super 中概述了super 的新用法,它是在 python 3.0 中实现的。特别相关;

    super().foo(1, 2)
    

    替换旧的:

    super(Foo, self).foo(1, 2)
    

    【讨论】:

      【解决方案2】:

      让我们使用以下类进行演示:

      class A(object):
          def m(self):
              print('m')
      
      class B(A): pass
      

      未绑定的super 对象不分派属性访问类,您必须使用描述符协议:

      >>> super(B).m
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      AttributeError: 'super' object has no attribute 'm'
      >>> super(B).__get__(B(), B)
      <super: <class 'B'>, <B object>>
      

      super 绑定到实例的对象给出绑定方法:

      >>> super(B, B()).m
      <bound method B.m of <__main__.B object at 0xb765dacc>>
      >>> super(B, B()).m()
      m
      

      super 绑定到类的对象提供函数(Python 2 中的未绑定方法):

      >>> super(B, B).m
      <function m at 0xb761482c>
      >>> super(B, B).m()
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      TypeError: m() takes exactly 1 positional argument (0 given)
      >>> super(B, B).m(B())
      m
      

      有关详细信息,请参阅 Michele Simionato 的“关于 Python Super 的须知”系列博文(123

      【讨论】:

      • 这个问题是专门针对 Python3 的,但是 Simionato 的博文系列是关于 Python2 的,并且提到 这样做的好处是可以避免在调用语法中重复类名,因为name 隐藏在私有名称的修改机制中。。这在 Python3 中不再适用,因此至少有一个优势已经过时了。
      • 这回答了 OP 的“每个人都做什么?”但它没有回答“你什么时候使用每一个?”此外,它实际上并没有解释“未绑定”与“绑定”;如果B 是类名,b = B() 是实例,则B 是未绑定对象,b 是绑定对象。
      猜你喜欢
      • 2020-06-18
      • 2013-02-10
      • 1970-01-01
      • 2023-01-15
      • 2011-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多