为什么在打印回溯时,Python会从当前目录进行读取? [英] Why does Python read from the current directory when printing a traceback?

查看:15
本文介绍了为什么在打印回溯时,Python会从当前目录进行读取?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

$ echo "Your code is bad and you should feel bad" > "<stdin>"
$ python
Python 3.6.0 (default, Dec 28 2016, 19:53:26) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 2 + '2'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    Your code is bad and you should feel bad
TypeError: unsupported operand type(s) for +: 'int' and 'str'

为什么Python将字符串"<stdin>"与该文件名匹配的文件混淆?如果遇到未处理的异常,我不希望Python尝试只从我的磁盘中读取任何文件。

您也可以使用"<string>"文件名:

获取它
$ echo "pining for the fjords" > "<string>"
$ python -c 'wat'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    pining for the fjords
NameError: name 'wat' is not defined

有什么方法可以防止这种行为,或者它是硬编码到REPL中的吗?

推荐答案

不跟踪与任何已编译字节码对应的源代码。它甚至可能不会读取源代码,直到它需要打印回溯,例如,如果从.pyc文件加载模块。

当Python需要打印回溯时,它会尝试查找与所有涉及的堆栈框架相对应的源代码。您在堆栈跟踪中看到的文件名和行号就是全部内容。如果它使用traceback模块,代码路径将经过linecacheexcludes filenames starting and ending with < and >中的一个部分,但默认的sys.excepthook不经过该路径。

default sys.excepthook通过本机调用PyErr_Display,最终使用_Py_DisplaySourceLine显示各个源代码行。_Py_DisplaySourceLine无条件地尝试在当前工作目录中查找该文件(出于某种原因-误导优化?),然后调用_Py_FindSourceFile搜索sys.path匹配该名称的文件(如果工作目录中没有该文件)。通常,它不会找到<stdin><string>文件,当它找不到文件时,它会跳过打印源代码,但如果找到一个文件,它就会从该文件打印。

我最初认为可以通过使用-I flag运行Python并将其置于隔离模式来防止出现这种情况。隔离模式的效果之一是从sys.path中删除脚本的目录。实验证明,这并没有改变事情,也就是我意识到_Py_DisplaySourceLine无论如何都会尝试工作目录。

通过排除本机代码路径中的<>文件名来修复此问题非常简单,就像linecache所做的那样。无条件在当前目录中搜索文件的代码也应更改。

这篇关于为什么在打印回溯时,Python会从当前目录进行读取?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆