Python 将关键字参数传递给自定义异常-异常
为什么以下两个代码段(Python 3.4)的结果不同: 以及:Python 将关键字参数传递给自定义异常-异常,python,exception,keyword-argument,Python,Exception,Keyword Argument,为什么以下两个代码段(Python 3.4)的结果不同: 以及: 这是因为错误参数会被覆盖,方法是在C级将它们转换为Python元组 下面是Python的BaseException类: 从第31行开始,我们看到以下内容: static PyObject * BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyBaseExceptionObject *self; self = (Py
这是因为错误参数会被覆盖,方法是在C级将它们转换为Python元组 下面是Python的BaseException类: 从第31行开始,我们看到以下内容:
static PyObject *
BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyBaseExceptionObject *self;
self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
if (!self)
return NULL;
/* the dict is created on the fly in PyObject_GenericSetAttr */
self->dict = NULL;
self->traceback = self->cause = self->context = NULL;
self->suppress_context = 0;
if (args) {
self->args = args;
Py_INCREF(args);
return (PyObject *)self;
}
self->args = PyTuple_New(0);
if (!self->args) {
Py_DECREF(self);
return NULL;
}
return (PyObject *)self;
}
同样,init调用具有相同的元组转换:
BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
{
PyObject *tmp;
if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
return -1;
tmp = self->args;
self->args = args;
Py_INCREF(self->args);
Py_XDECREF(tmp);
return 0;
}
简而言之,self.args被转换为元组,元组又被转换回字符串,这导致了差异
BaseException类是(我相信)作为必需参数为所有方法包装器调用的
如果传递一个不可接受的参数(如整数),这是可以理解的:
>>类自定义异常(异常):
... 定义初始化(自):
... 超级(CustomException,self)。\uuuu init\uuuuu('a'))
... self.args=1
... 定义报告(自我):
... 打印(self.args)
... 返回“”
...
>>>CustomException()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第4行,在_init中__
TypeError:“int”对象不可编辑
这个故事的寓意是:不要给你的变量命名,因为它们是不断被重新定义的,并且是你正在使用的类的关键术语
static PyObject *
BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyBaseExceptionObject *self;
self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
if (!self)
return NULL;
/* the dict is created on the fly in PyObject_GenericSetAttr */
self->dict = NULL;
self->traceback = self->cause = self->context = NULL;
self->suppress_context = 0;
if (args) {
self->args = args;
Py_INCREF(args);
return (PyObject *)self;
}
self->args = PyTuple_New(0);
if (!self->args) {
Py_DECREF(self);
return NULL;
}
return (PyObject *)self;
}
BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
{
PyObject *tmp;
if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
return -1;
tmp = self->args;
self->args = args;
Py_INCREF(self->args);
Py_XDECREF(tmp);
return 0;
}
>>> class CustomException(Exception):
... def __init__(self):
... super(CustomException, self).__init__('a')
... self.args = 1
... def __repr__(self):
... print(self.args)
... return ''
...
>>> CustomException()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
TypeError: 'int' object is not iterable