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)