[英]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
,我发现弃用警告很烦人。 所以我开始做我的事来解决这个问题。
首先(和更老的,已经解决的问题): SafeConfigParser
是SafeConfigParser
中的旧式类,所以我不能在我的后代类中调用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
和SafeConfigParser
。在我的类中交换两个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.