为什么不能在Python中同时继承dict和Exception?
我有一个这样的类:
class ConstraintFailureSet(dict, Exception) :
"""
Container for constraint failures. It act as a constraint failure itself
but can contain other constraint failures that can be accessed with a dict syntax.
"""
def __init__(self, **failures) :
dict.__init__(self, failures)
Exception.__init__(self)
print isinstance(ConstraintFailureSet(), Exception)
True
raise ConstraintFailureSet()
TypeError: exceptions must be classes, instances, or strings (deprecated), not ConstraintFailureSet
这到底是怎么回事?
更糟糕的是,我不能尝试使用 super(),因为 Exception 是个老旧的基类……
编辑:是的,我试过改变继承和初始化的顺序。
编辑2:我在 Ubuntu 8.10 上使用 CPython 2.4。你永远不知道这些信息是否有用;不过,这个小难题让我的三个同事都哑口无言。你今天会是我最好的朋友……
6 个回答
3
没有特别原因,只是找到了解决办法
目前我还不知道为什么会这样,但我用 UserDict.UserDict
这个方法绕过了这个问题。虽然这个方法比较慢,因为它是纯 Python 写的,但我觉得在这个应用的这个部分,速度慢也不会造成太大麻烦。
不过我还是很想知道真正的答案 ;-)
4
这段代码有什么问题呢?
class ConstraintFailure( Exception ):
def __init__( self, **failures ):
self.failures= failures # already a dict, don't need to do anything
def __getitem__( self, key ):
return self.failures.get(key)
这是一个异常,它里面有一个叫做 failures
的内部字典,里面存放着其他的异常信息。
你能不能更新一下你的问题,列出一些这个异常无法处理的具体情况呢?
try:
raise ConstraintFailure( x=ValueError, y=Exception )
except ConstraintFailure, e:
print e['x']
print e['y']
<type 'exceptions.ValueError'>
<type 'exceptions.Exception'>
21
在C语言中实现了Exception
和dict
这两个东西。
你可以用以下方法来测试这个:
>>> class C(object): pass
...
>>> '__module__' in C.__dict__
True
>>> '__module__' in dict.__dict__
False
>>> '__module__' in Exception.__dict__
False
因为Exception
和dict
在内部存储数据的方式不同,所以它们不兼容,因此你不能同时从这两个类继承。
在后来的Python版本中,当你尝试定义这个类时,你应该会遇到一个异常:
>>> class foo(dict, Exception):
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
multiple bases have instance lay-out conflict