【问题标题】:Can I use Python 3 super() in Python 2.5.6?我可以在 Python 2.5.6 中使用 Python 3 super() 吗?
【发布时间】:2011-10-10 21:06:11
【问题描述】:

我可以在 Python 2.5.6 中使用干净的 Python 3 super() 语法吗?
也许有某种__future__ 导入?

【问题讨论】:

    标签: python python-3.x super python-2.5


    【解决方案1】:

    我意识到这个问题已经过时了,当时选择的答案可能是正确的,但它不再完整。您仍然不能在 2.5.6 中使用 super(),但 python-future 为 2.6+ 提供了 back-ported implementation

    安装python-future

    % pip install future
    

    下面是builtinssuper的重新定义:

    % python
    ...
    >>> import sys
    >>> sys.version_info[:3]
    (2, 7, 9)
    >>>
    >>> super
    <type 'super'>
    >>>
    >>> from builtins import *
    >>> super
    <function newsuper at 0x000000010b4832e0>
    >>> super.__module__
    'future.builtins.newsuper'
    

    可以这样使用:

    from builtins import super
    
    class Foo(object):
        def f(self):
            print('foo')
    
    class Bar(Foo):
        def f(self):
            super().f() # <- whoomp, there it is
            print('bar')
    
    b = Bar()
    b.f()
    

    哪个输出

    foo
    bar
    

    如果您使用pylint,您可以通过注释禁用旧版警告:

    # pylint: disable=missing-super-argument
    

    【讨论】:

      【解决方案2】:

      您不能使用不包含类型/类的纯 super() 调用。您也无法实施可行的替代品。 Python 3.x 包含对启用裸 super() 调用的特殊支持(它在类中定义的所有函数中放置一个 __class__ 单元变量 - 请参阅 PEP 3135


      更新

      从 Python 2.6+ 开始,裸 super() 调用可以通过 future Python 包使用。有关说明,请参阅 posita's answer

      【讨论】:

      • 谢谢。我很困惑,因为这个 PEP 的早期版本说你会用 from __future__ import new_super 导入它,这是行不通的。
      【解决方案3】:

      不,你不能。但是您可以在 Python 3 中使用 Python 2 的 super()

      【讨论】:

        【解决方案4】:

        注意这是一个糟糕的“解决方案”,我发布它只是为了确保您不要在家里这样做!
        我再说一遍:不要这样做

        可能有人会考虑使用这个 mixin

        class Super(object):
            def super(self):
                return super(self.__class__, self)
        

        获取self.super()

        class A(object, Super):
            def __init__(self):
                print "A"
        
        class B(A):
            def __init__(self):
                print "B"
                self.super().__init__()
        

        屈服:

         >>> a = A()
         A
         >>> b = B()
         B
         A
        

        但要注意:这个self.super() 不等于super(B, self) - 如果A 也称为self.super().__init__()B 的构造将导致A 构造函数无限期地调用自己,因为self.__class__ 将保持为B。这是由于缺少accepted answer 中提到的__class__。您可以使用隐藏状态机或复杂的元类来解决此问题,例如检查self.__class__.mro() 中实际班级的位置,但这真的值得吗?应该不会吧……

        【讨论】:

          猜你喜欢
          • 2012-05-16
          • 1970-01-01
          • 1970-01-01
          • 2015-07-30
          • 2019-09-09
          • 1970-01-01
          • 2020-03-13
          • 1970-01-01
          相关资源
          最近更新 更多