Python 2和3兼容`super`和类在Py2中是旧式的,但在Py3中变成了新式

exh*_*uma 5 python multiple-inheritance super

我有一个使用的项目,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
Run Code Online (Sandbox Code Playgroud)

如果有必要,这样可以使课程成为新式.为了摆脱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
Run Code Online (Sandbox Code Playgroud)

一路上我还修了一条我错过了之前改变的路线:

@@ -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:
Run Code Online (Sandbox Code Playgroud)

这一变化引发了一个有趣的错误:

AttributeError: 'Config' object has no attribute '_sections'
Run Code Online (Sandbox Code Playgroud)

这让我相信__init__ConfigParser是不叫.确实做出以下修改:

- class ConfigResolverBase(object, SafeConfigParser):
+ class ConfigResolverBase(SafeConfigParser, object):
Run Code Online (Sandbox Code Playgroud)

我的代码现在对Python 2和3都运行良好,但是我不确定的是:代理返回的代码super总是一样吗?"在我的情况下,我继承了两个objectSafeConfigParser.交换我的类定义中的两个基数super返回但是在所有平台上的所有Python实现中,这是否保证是稳定的?或者我应该明确地调用SafeConfigParser.get(self, ...)?这是调用基础的所有"老方法"...

Mar*_*ers 2

是的,它可以保证跨 Python 版本的稳定性。搜索顺序称为方法解析顺序,或 MRO,这个顺序自 Python 2.3 以来一直保持不变。

有关如何确定顺序的更多详细信息,请参阅Python 2.3 方法解析顺序文档

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