Pulpcode

捕获,搅碎,拼接,吞咽

0%

python的py和pyc文件

今天有一个朋友问我,是否在更新一个py文件的时候,pyc文件也会跟着更新。

这其实是一个很有趣的问题。

我们来做个实验就知道了,首先我来写这样两段代码:

foo.py 文件
1
2
3
# -*- coding: utf-8 -*-
def echo():
return "hehe"
bar.py 文件
1
2
3
4
5
# -*- coding: utf-8 -*-
import foo

if __name__ == '__main__':
print foo.echo()

执行结果:

$ python bar.py
$ hehe

这个时候,目录中的文件是这个样子的:

$ ls
bar.py foo.py foo.pyc

现在我们对foo.py中的代码进行修改:

1
2
3
# -*- coding: utf-8 -*-
def echo():
return "nima"

这个时候再次执行代码,将会显示如下结果。

$ python bar.py
$ nima

这说明随着py文件的更新,pyc文件也进行了更新。

问题1: 为什么有人会担心pyc不是最新的。

作为一个程序员来说,会有这样的担心是因为大多数程序的bug,常常是因为你获得的数据,并不是你想要的到的。

按道理来说,数据仅能有一个”发源地”,每次获取都要从发源地重新生成(就像是pycpy的发源地)。但这很没效率,所以我们会做缓存文件。虽然缓存文件也有发源地,但生成之后便和发源地“没有任何瓜葛了”。
所以它并不能保证和”发源地”的数据同步,这样就会引发一系列问题。虽然在我们刚才的测试中,pypyc不是这样的,但是另一些情况下就不同了。

比如在调试web程序的时候,常常会因为浏览器的缓存深受其害,比如你已经修改了某个地方,但是页面却没有显示到最新的。这会让你不知所措。

elisp

在 emacs中,你的所有扩展都是用elisp来写的,这些文件以el结尾。你可以指定自己的emacs如何去载入它们。

elisp为了保证emacs有效率的载入el文件,使用了类似于pythonpyc文件,但是emacs并不自动生成这些字节码文件,需要你在emacs中使用命令去生成它们。

byte-compile-file

而且在emacs,即使你改变了el文件,emacs还是会优先去载入elc文件。

但在 emacs24.4中,加入了这样一个新的特性。load-prefer-newer

它能让你在载入一个模块的时候进行选择。如果这个变量被设置为t(rue),而且elelc文件同时存在,并且你在代码中也没有指定哪个文件将被载入,那么emacs将优先载入较新的文件。
而默认的,这个变量的值为 nil, 它只会载入elc文件。

小插曲:

你会发现在python的例子中。只有foo文件才有自己的pyc文件,bar文件并没有自己的pyc文件,我想这是因为作为执行文件来说,要常常修改,本身不像库那样长久使用,所以没有必要为其生成一个pyc字节码文件。
同样的,Emacser们把moudle类型的el文件编译成elc,而非脚本文件。