为什么错误跟踪显示已编辑的脚本而不是实际运行的脚本? [英] Why does error traceback show edited script instead of what actually ran?

查看:102
本文介绍了为什么错误跟踪显示已编辑的脚本而不是实际运行的脚本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下最小示例:

当我保存以下脚本并从终端运行它时,

When I save the following script and run it from terminal,

import time

time.sleep(5)
raise Exception

该代码将在睡眠五秒钟后引发错误,并留下以下回溯.

the code will raise an error after sleeping five seconds, leaving the following traceback.

回溯(最近通话最近):
  文件"test/minimal_error.py",在< module>
中的第4行    引发异常
例外

Traceback (most recent call last):
  File "test/minimal_error.py", line 4, in <module>
    raise Exception
Exception

现在,我运行脚本,在5秒钟的睡眠期间,我在中间添加了一行.

Now, say, I run the script, and during the 5-second-sleep, I add a line in the middle.

import time

time.sleep(5)
a = 1
raise Exception

python解释器从睡眠中唤醒并到达下一行raise Exception后,它将引发错误,但会留下以下回溯.

After the python interpreter wakes up from the sleep and reaches the next line, raise Exception, it will raise the error, but it leaves the following traceback.

回溯(最近通话最近):
  文件"test/minimal_error.py",在< module>
中的第4行     a = 1
例外

Traceback (most recent call last):
  File "test/minimal_error.py", line 4, in <module>
    a = 1
Exception

因此,一个明显的问题是它不会打印出导致错误的实际代码.尽管它提供了正确的行号(正确地反映了正在运行的脚本的版本,虽然可以理解地没有用)和正确的错误消息,但我真的不知道是哪段代码真正导致了错误.

So the obvious problem is that it doesn't print the actual code that caused the error. Although it gives the correct line number (correctly reflecting the version of the script that is running, while understandably useless) and a proper error message, I can't really know what piece of code actually caused the error.

在实际实践中,我实现了程序的一部分,运行该程序以查看该部分是否运行良好,并且在该程序仍在运行时,我继续进行下一步要实现的事情.当脚本引发错误时,我必须找到导致错误的实际代码行.我通常只是阅读错误消息,然后尝试推断出引起该错误的原始代码.有时很难猜测,因此我将脚本复制到剪贴板,并通过撤消运行脚本后编写的内容来回滚代码,检查导致错误的行,然后从剪贴板粘贴回去.

In real practice, I implement one part of a program, run it to see if that part is doing fine, and while it is still running, I move on to the next thing I have to implement. And when the script throws an error, I have to find which actual line of code caused the error. I usually just read the error message and try to deduce the original code that caused it. Sometimes it isn't easy to guess, so I copy the script to clipboard and rollback the code by undoing what I've written after running the script, check the line that caused error, and paste back from clipboard.

解释器显示代码当前"版本的第4行的a = 1,而不是代码运行"版本的第4行的raise Exception,是否有任何可以理解的原因?如果解释器知道第4行"引起了错误并且错误消息为"Exception",为什么它不能说命令raise Exception引发了该错误?

Is there any understandable reason why the interpreter shows a = 1, which is line 4 of the "current" version of the code, instead of raise Exception, which is line 4 of the "running" version of the code? If the interpreter knows "line 4" caused the error and the error message is "Exception", why can't it say the command raise Exception raised it?

我不太确定这个问题是否在这里,但我认为我不能从

I'm not really sure if this question is on-topic here, but I don't think I can conclude it off-topic from what the help center says. It is about "[a] software [tool] commonly used by programmers" (the Python interpreter) and is "a practical, answerable problem that is unique to software development," I think. I don't think it's opinion-based, because there should be a reason for this choice of implementation.

(在Python 2.7.16、3.6.8、3.7.2和3.7.3中观察到相同,因此它似乎不是特定于版本的,而是在Python中发生的事情.)

(Observed the same in Python 2.7.16, 3.6.8, 3.7.2, and 3.7.3, so it doesn't seem to be version-specific, but a thing that just happens in Python.)

推荐答案

直接原因是Python重新打开文件并再次读取指定的行以将其打印在错误消息中.那么,为什么它在开始时已经读取了文件就需要这样做呢?因为它不会将源代码保留在内存中,所以只能生成生成的字节码.

The immediate reason is that Python re-opens the file and reads the specified line again to print it in error messages. So why would it need to do that when it already read the file in the beginning? Because it doesn't keep the source code in memory, only the generated byte code.

事实上,Python永远不会一次将源文件的全部内容保存在内存中.相反,词法分析器将一次读取文件并产生一个令牌,然后解析器将解析并转换为字节码.使用令牌完成解析器后,它就消失了.

In fact, Python will never hold the entire contents of the source file in memory at one time. Instead the lexer will read from the file and produce one token at a time, which the parser then parses and turns into byte code. Once the parser is done with a token, it's gone.

所以返回原始源代码的唯一方法是再次打开源文件.

So the only way to get back at the original source code is to open the source file again.

这篇关于为什么错误跟踪显示已编辑的脚本而不是实际运行的脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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