【问题标题】:Python 2 & 3 compatibility with `super` and classes who were old-style in Py2 but became new-style in Py3Python 2 & 3 与 `super` 和在 Py2 中是旧样式但在 Py3 中变成新样式的类的兼容性
【发布时间】:2014-01-02 15:47:02
【问题描述】:

我有a project,它使用SafeConfigParser,我希望它兼容 Python2 和 3。现在,SafeConfigParser 自 Python 3.2 起已弃用,我发现弃用警告很烦人。所以我开始着手解决这个问题。

首先(而且更老,已经解决的问题):SafeConfigParser 是 Python2 中的旧式类,所以我不能在我的后代类中调用 super。为了有更一致的行为,我写了以下内容:

try:
    # Python 2
    class ConfigResolverBase(object, SafeConfigParser):
        """
        A default "base" object simplifying Python 2 and Python 3
        compatibility.
        """
        pass
except TypeError:
    # Python 3
    class ConfigResolverBase(SafeConfigParser):
        """
        A default "base" object simplifying Python 2 and Python 3
        compatibility.
        """
        pass

如有必要,这可以很好地使课程具有新风格。为了摆脱DeprecationWarning,我将代码更改为:

if sys.hexversion < 0x030000F0:
    # Python 2
    class ConfigResolverBase(object, SafeConfigParser):
        """
        A default "base" object simplifying Python 2 and Python 3
        compatibility.
        """
        pass
else:
    # Python 3
    class ConfigResolverBase(ConfigParser):
        """
        A default "base" object simplifying Python 2 and Python 3
        compatibility.
        """
        pass

在此过程中,我还修复了我之前错过的一条线:

@@ -275,7 +276,7 @@ class Config(ConfigResolverBase):
             have_default = False

         try:
-            value = SafeConfigParser.get(self, section, option, **kwargs)
+            value = super(Config, self).get(section, option, **kwargs)
             return value
         except (NoSectionError, NoOptionError) as exc:
             if have_default:

那个的改变导致了一个有趣的错误:

AttributeError: 'Config' object has no attribute '_sections'

这让我相信 ConfigParser__init__ 没有被调用。并且确实进行了以下更改修复了该问题:

- class ConfigResolverBase(object, SafeConfigParser):
+ class ConfigResolverBase(SafeConfigParser, object):

我的代码现在在 Python 2 和 3 上都可以正常工作,但我不确定的是:super 返回的代理是否总是相同的?” 在我的情况下,我继承自 object 和 @987654336 @. 在我的类定义中交换两个基数使super 返回正确的基数。但这是否保证在所有平台上的所有 Python 实现中都是稳定的?或者我应该显式调用SafeConfigParser.get(self, ...)?毕竟这是“调用基地的旧方式...

【问题讨论】:

    标签: python multiple-inheritance super


    【解决方案1】:

    是的,它保证跨 Python 版本稳定。搜索顺序称为方法解析顺序,或 MRO,此顺序自 Python 2.3 以来一直相同。

    有关如何确定订单的更多详细信息,请参阅Python 2.3 Method Resolution Order documentation

    您可以通过查看给定类的.__mro__ 属性来检查MRO;它是按方法解析顺序排列的类的元组。

    【讨论】:

    • 感谢闪电般的快速回答!我正在寻找 MRO,但我不完全确定它是否稳定。感谢您确认。
    【解决方案2】:

    我也在使用SafeConfigParser 做一些工作。要使其适用于旧式和新式类,您可以检查它是否是object 的子类。新式类继承自 object,而旧式类不继承。

    例子:

    class MyClass(SafeConfigParser):
        def __init__(self):
            if issubclass(SafeConfigParser, object):
                # new style class, call super
                super(MyClass, self).__init__()
            else:
                # old style class, call __init__ manually
                SafeConfigParser.__init__(self)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-22
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-05
      相关资源
      最近更新 更多