gpt4 book ai didi

python - 将关键字参数传递给自定义异常 - 异常

转载 作者:行者123 更新时间:2023-11-28 17:35:42 24 4
gpt4 key购买 nike

为什么我得到以下两个代码片段的不同结果 (Python 3.4):

class MainError(Exception):
def __init__(self, msg, **parms):
super().__init__()
self.msg = msg
self.parms = parms
print('Parms original', parms)

def __str__(self):
return self.msg + ':' + str(self.parms)

class SubError(MainError):
def __init__(self, msg, **parms):
super().__init__(msg, **parms)

try:
raise SubError('Error occured', line = 22, col = 11)
except MainError as e:
print(e)


>>>
Parms original {'line': 22, 'col': 11}
Error occured:{'line': 22, 'col': 11}

和:

class MainError(Exception):
def __init__(self, msg, **args):
super().__init__()
self.msg = msg
self.args = args
print('Parms original', args)

def __str__(self):
return self.msg + ':' + str(self.args)

class SubError(MainError):
def __init__(self, msg, **args):
super().__init__(msg, **args)

try:
raise SubError('Error occured', line = 22, col = 11)
except MainError as e:
print(e)


>>>
Parms original {'line': 22, 'col': 11}
Error occured:('line', 'col')

最佳答案

这是因为错误参数被覆盖,通过将它们转换为 C 级别的 Python 元组。

这是 Python 的 BaseException 类: https://hg.python.org/cpython/file/tip/Objects/exceptions.c

从第 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 类作为必需参数被调用(我相信)所有方法包装器。

如果向它传递一个不可迭代的参数(例如整数),这是很明显的:

>>> 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

这个故事的寓意:不要给你的变量命名,因为这些词会不断被重新定义,并且是你正在使用的类的关键术语。

关于python - 将关键字参数传递给自定义异常 - 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30745668/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com