python2&3与'super'和Py2中旧样式但在Py3中变为newstyle的类兼容

2024-09-27 21:29:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有a project,它使用SafeConfigParser,我希望它与Python2和3兼容。现在,自从python3.2以来,SafeConfigParser就被弃用了,我发现弃用警告很烦人。所以我就去做我的生意来弥补这一点。在

第一个(也是更古老的,已经解决的问题):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,我将代码改为:

^{pr2}$

在此过程中,我还修正了一条我之前没有改的线路:

@@ -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):

我的代码现在对python2和python3都可以正常工作,但是我不确定的是:super返回的代理是否总是相同的?”在我的例子中,我同时继承了object和{}。交换类定义中的两个基使super返回正确的基。但是这是否保证在所有平台上的所有Python实现中都是稳定的呢?或者我应该显式调用SafeConfigParser.get(self, ...)?这毕竟是所谓基地的“老方法”。。。在


Tags: andselfconfigdefaultbasegetobjectvalue
2条回答

是的,它可以保证跨Python版本的稳定性。搜索顺序称为方法解析顺序(methodresolutionorder,简称MRO),自python2.3以来,这个顺序一直保持不变。在

有关如何确定顺序的详细信息,请参阅Python 2.3 Method Resolution Order documentation。在

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

我也在用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)

相关问题 更多 >

    热门问题