在Python中,SyntaxError
对象具有print_file_and_line
属性:
>>> SyntaxError.print_file_and_line
<member 'print_file_and_line' of 'SyntaxError' objects>
>>> help(SyntaxError.print_file_and_line)
Help on member descriptor builtins.SyntaxError.print_file_and_line:
print_file_and_line
exception print_file_and_line
>>> s = SyntaxError()
>>> s.print_file_and_line
# None
>>> s.print_file_and_line = [{'what am I for'}]
>>> s.print_file_and_line
[{'what am I for'}]
这是做什么用的?
据我所知,它的存在被用作标记来触发print_exception
中pythonrun.c
中的一些额外代码,以打印出语法错误的文件和行以及该行的实际文本在打印出其余堆栈跟踪之后,用尖号标记错误的位置。请记住,带有语法错误的代码永远不会执行-毕竟导入失败-因此它实际上并不是堆栈跟踪的一部分。我得到的印象是print_file_and_line
不仅仅是实现的一部分,还包括您可以与之有效交互的内容。
[当您从语法错误中看到回溯打印时,由于该代码,下面标有<<<
的行将被打印。
$ echo ')' > syntax_error.py
$ python -c 'import syntax_error'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "syntax_error.py", line 1 <<<
) <<<
^ <<<
SyntaxError: invalid syntax
代码在pythonrun.c
中:
它看起来像这样:
if (err == 0 &&
_PyObject_HasAttrId(value, &PyId_print_file_and_line))
{
PyObject *message, *filename, *text;
int lineno, offset;
if (!parse_syntax_error(value, &message, &filename,
&lineno, &offset, &text))
PyErr_Clear();
else {
PyObject *line;
Py_DECREF(value);
value = message;
line = PyUnicode_FromFormat(" File \"%S\", line %d\n",
filename, lineno);
Py_DECREF(filename);
if (line != NULL) {
PyFile_WriteObject(line, f, Py_PRINT_RAW);
Py_DECREF(line);
}
if (text != NULL) {
print_error_text(f, offset, text);
Py_DECREF(text);
}
/* Can't be bothered to check all those
PyFile_WriteString() calls */
if (PyErr_Occurred())
err = -1;
}
}