Python 2&;3与'super'和在Py2中是旧样式但在Py3中成为新样式的类的兼容性

Python 2&;3与'super'和在Py2中是旧样式但在Py3中成为新样式的类的兼容性,python,multiple-inheritance,super,Python,Multiple Inheritance,Super,我有一个使用SafeConfigParser的工具,我希望它与Python2和3兼容。现在,SafeConfigParser已被弃用,因为Python 3.2和我发现弃用警告很烦人。所以我开始着手解决这个问题 首先(也是更老的,已经解决的问题):SafeConfigParser是Python2中的一个老式类,所以我不能在我的后代类中调用super。为了使行为更加一致,我写了以下内容: try: # Python 2 class ConfigResolverBase(object,

我有一个使用
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
如果必要的话,这很好地使这个班级成为新的风格。为了摆脱弃用警告,我将代码更改为:

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
这一变化导致了一个有趣的错误:

AttributeError: 'Config' object has no attribute '_sections'
这让我相信,
ConfigParser
\uuu init\uuu
没有被调用。实际上,做出以下修改:

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

我的代码现在在Python2和Python3上都运行良好,但我不确定的是:
super
返回的代理是否总是相同的?“在我的例子中,我从
对象
安全配置解析器
继承。交换我的类定义中的两个基使得
super
返回正确的基。但这是否保证在所有平台上的所有Python实现中都是稳定的?或者我应该显式调用
SafeConfigParser.get(self,…)
?这毕竟是调用base的“老方法”…

是的,它在Python版本中是稳定的。搜索顺序称为方法解析顺序(methodresolutionorder,MRO),这个顺序自Python 2.3以来一直保持不变

有关如何确定订单的更多详细信息,请参阅


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

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

例如:

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)

谢谢你闪电般的回答!我在查看MRO,但我不完全确定它是否稳定。谢谢你的确认。
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)