簡體   English   中英

Python 2和3兼容`super`和類在Py2中是舊式的,但在Py3中變成了新式

[英]Python 2 & 3 compatibility with `super` and classes who were old-style in Py2 but became new-style in Py3

我有一個使用SafeConfigParser 的項目 ,我希望它與Python2和3兼容。 現在,從Python 3.2開始不推薦使用SafeConfigParser ,我發現棄用警告很煩人。 所以我開始做我的事來解決這個問題。

首先(和更老的,已經解決的問題): SafeConfigParserSafeConfigParser中的舊式類,所以我不能在我的后代類中調用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返回的代理總是一樣的嗎?“在我的情況下,我繼承了objectSafeConfigParser 。在我的類中交換兩個SafeConfigParser定義使super返回正確的。但這是否保證在所有平台上的所有Python實現中都是穩定的?或者我應該明確地調用SafeConfigParser.get(self, ...) ?這是所有的“老方法”呼喚基地......

是的,它在Python版本中保證穩定。 搜索順序稱為方法解析順序(MRO),此順序與Python 2.3相同。

有關如何確定訂單的更多詳細信息,請參閱Python 2.3方法解析訂單文檔

您可以通過查看給定類的.__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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM