`SyntaxError.print_file_and_line` 是做什么用的?
What is `SyntaxError.print_file_and_line` for?
在 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;
}
}
我尝试了一个实验来测试这个。如果我 运行 这个脚本:
class FakeSyntaxException(Exception):
print_file_and_line = None
def __init__(self):
self.text = 'Here is some text'
self.lineno = 123
self.offset = 6
self.msg = 'Something went wrong'
self.filename = 'example.txt'
raise FakeSyntaxException()
我明白了:
$ python3 python_syntax_test.py
Traceback (most recent call last):
File "python_syntax_test.py", line 10, in <module>
raise FakeSyntaxException()
File "example.txt", line 123
Here is some text
^
__main__.FakeSyntaxException: Something went wrong
而如果我注释掉 print_file_and_line
行,我只会看到:
$ python3 python_syntax_test.py
Traceback (most recent call last):
File "python_syntax_test.py", line 10, in <module>
raise FakeSyntaxException()
__main__.FakeSyntaxException
在 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;
}
}
我尝试了一个实验来测试这个。如果我 运行 这个脚本:
class FakeSyntaxException(Exception):
print_file_and_line = None
def __init__(self):
self.text = 'Here is some text'
self.lineno = 123
self.offset = 6
self.msg = 'Something went wrong'
self.filename = 'example.txt'
raise FakeSyntaxException()
我明白了:
$ python3 python_syntax_test.py
Traceback (most recent call last):
File "python_syntax_test.py", line 10, in <module>
raise FakeSyntaxException()
File "example.txt", line 123
Here is some text
^
__main__.FakeSyntaxException: Something went wrong
而如果我注释掉 print_file_and_line
行,我只会看到:
$ python3 python_syntax_test.py
Traceback (most recent call last):
File "python_syntax_test.py", line 10, in <module>
raise FakeSyntaxException()
__main__.FakeSyntaxException