假设我定义了以下异常:
>>> class MyError(Exception):
... def __init__(self, arg1):
... pass
然后我实例化该类以创建一个异常对象:
>>> e = MyError('abc')
>>> e.args
('abc',)
此处如何设置args
属性? (在__init__
中,我什么也没做。)
答案 0 :(得分:3)
file name
被实现为具有args
和__get__
方法的数据描述符。
这发生在__set__
内,如@bakatrouble所述。除其他外,BaseException.__new__
内部发生的事情大致类似于下面的Python代码:
BaseException.__new__
在 Python 3.7.0 alpha 1 的C代码中,上面的Python代码如下所示(检查Python的C代码是否存在过去或未来的差异):
class BaseException:
def __new__(cls, *args):
# self = create object of type cls
self.args = args # This calls: BaseException.args.__set__(self, args)
...
return self
以交互方式进行实验:
BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
# other things omitted...
self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
# many things follow...
if (args) {
self->args = args;
Py_INCREF(args);
return (PyObject *)self;
}
# many more things follow
}
>>> e = Exception('aaa')
>>> e
Exception('aaa',)
因此,当>>> BaseException.args.__set__(e, ('bbb',))
>>> e
Exception('bbb',)
>>> BaseException.args.__get__(e)
('bbb',)
或其任何子类的对象被创建时,args
使你的眼睛看起来向天堂的神奇灵感发生在BaseException.__new__
。
答案 1 :(得分:1)
它是在BaseException.__new__()
方法中设置的,可以在此处看到:source code
注意:在Python 2.7中,它是在BaseException.__init__()
方法中设置的,因此覆盖使.args
dict始终为空(不确定是否指向正确的行):source code < / p>