python脚本路径在编译后保持不变

python脚本路径在编译后保持不变,python,compiler-construction,path,compilation,Python,Compiler Construction,Path,Compilation,我意识到在编译python脚本之后,它修复了该脚本的路径信息 例如: 我有一个python脚本/tmp/src/foo.py,它有一个print命令 print foo 现在我正在编译这段代码,并将其移动到已编译目录 python -m compileall -f /tmp/src/foo.py mv /tmp/src/foo.pyc /tmp/compiled/ 然后我运行脚本,它给出了错误,因为我例外 python /tmp/compiled/foo.pyc Traceback (mos

我意识到在编译python脚本之后,它修复了该脚本的路径信息

例如: 我有一个python脚本/tmp/src/foo.py,它有一个print命令

print foo
现在我正在编译这段代码,并将其移动到已编译目录

python -m compileall -f /tmp/src/foo.py
mv /tmp/src/foo.pyc /tmp/compiled/
然后我运行脚本,它给出了错误,因为我例外

python /tmp/compiled/foo.pyc
Traceback (most recent call last):
  File "/tmp/src/foo.py", line 1, in <module>  # focus heree
    print foo
NameError: name 'foo' is not defined
python/tmp/compiled/foo.pyc
回溯(最近一次呼叫最后一次):
文件“/tmp/src/foo.py”,第1行,在这里聚焦
印刷食品
NameError:未定义名称“foo”
正如您所意识到的,脚本的文件名在编译之前作为其名称出现错误。(与我给编译命令的路径完全相同)

事实上,我对这种情况没有问题,我只是想知道。原因是什么?有没有办法看到错误中的真实路径

在我看来,我们不能更改二进制文件,但也许我们可以在运行编译代码时为python提供一个命令行参数,或者我们可以在源代码中添加一个代码段


谢谢

您的问题源于这样一个概念,即Python模块的编译版本可以而且应该在特定条件下移动。事实上,我以前从未听说过这样的事情,因此,在给出一个认可这种事情的规范之前,我要说这是一种滥用,您很幸运能够运行
.pyc
文件,而不需要
.py

如果您认为
.pyc
文件仅仅是原始文件编译版本的缓存,那么您可以很容易地解释您观察到的所有现象:原始
.py
文件的路径存储在
.pyc
中,以及来自该源的所有其他内容。如果移动,内容当然保持不变,并将在错误消息中使用

无法在错误消息中看到“真实”路径,因为加载后,
.pyc
文件的位置不再为人所知;只考虑它的内容,而不考虑它的位置,因为合并这两个东西是编译的一个步骤。解释器不会再次将任何内容编译到已编译的模块。它照原样去做


修补
.pyc
文件以显示不同的路径似乎也没有意义,因为该消息用于帮助您调试问题。您可能不会调试
.pyc
文件中的任何内容,而只调试
.py
文件中的任何内容。因此,在错误消息中显示该文件的路径似乎更合适。

您的问题源自这样一个概念,即Python模块的编译版本可以而且应该在特定条件下移动。事实上,我以前从未听说过这样的事情,因此,在给出一个认可这种事情的规范之前,我要说这是一种滥用,您很幸运能够运行
.pyc
文件,而不需要
.py

如果您认为
.pyc
文件仅仅是原始文件编译版本的缓存,那么您可以很容易地解释您观察到的所有现象:原始
.py
文件的路径存储在
.pyc
中,以及来自该源的所有其他内容。如果移动,内容当然保持不变,并将在错误消息中使用

无法在错误消息中看到“真实”路径,因为加载后,
.pyc
文件的位置不再为人所知;只考虑它的内容,而不考虑它的位置,因为合并这两个东西是编译的一个步骤。解释器不会再次将任何内容编译到已编译的模块。它照原样去做


修补
.pyc
文件以显示不同的路径似乎也没有意义,因为该消息用于帮助您调试问题。您可能不会调试
.pyc
文件中的任何内容,而只调试
.py
文件中的任何内容。因此,在错误消息中显示该文件的路径似乎更合适。

您所说的“有没有办法看到错误中的真实路径?”是什么意思?你已经看到了真正的道路,对吗?你想在跟踪中看到什么?为什么你想手动“编译”一个脚本,为什么你想把它放在不同的目录中?@Probled Superver我看到了源路径。我想查看编译代码的路径。pyc不应该与原始源代码分离,它们只是一个“缓存”。这就是为什么你要走这条路。“你为什么要做这样的事?”浮士德:你没读过这个问题吗!我没有问题。我只是想知道。你说的“有没有办法看到错误中的真实路径?”是什么意思?你已经看到了真正的道路,对吗?你想在跟踪中看到什么?为什么你想手动“编译”一个脚本,为什么你想把它放在不同的目录中?@Probled Superver我看到了源路径。我想查看编译代码的路径。pyc不应该与原始源代码分离,它们只是一个“缓存”。这就是为什么你要走这条路。“你为什么要做这样的事?”浮士德:你没读过这个问题吗!我没有问题。我只是想知道。我甚至可以在其他机器上运行.pyc而不运行.py,即使它是一个长脚本。那么呢?这只是因为字节码在任何地方都是相同的。我想指定它,因为你说“你很幸运能够运行.pyc文件,而不需要.py文件。”“直到有一个规范批准这样的事情”-批准这种使用。“对于同一个模块,有一个名为spam.pyc的文件(使用-O时为spam.pyo)而没有spam.py的文件是可能的。这可以用来分发一个Python代码库,它的形式相当难进行反向工程。”很好,但并不是说主模块也可以这样处理(这里就是这种情况)。但另一方面,这种区分很可能是人为的