今天有一个朋友问我,是否在更新一个py
文件的时候,pyc
文件也会跟着更新。
这其实是一个很有趣的问题。
我们来做个实验就知道了,首先我来写这样两段代码:
foo.py 文件
1 | # -*- coding: utf-8 -*- |
bar.py 文件
1 | # -*- coding: utf-8 -*- |
执行结果:
$ python bar.py
$ hehe
这个时候,目录中的文件是这个样子的:
$ ls
bar.py foo.py foo.pyc
现在我们对foo.py
中的代码进行修改:
1 | # -*- coding: utf-8 -*- |
这个时候再次执行代码,将会显示如下结果。
$ python bar.py
$ nima
这说明随着py
文件的更新,pyc
文件也进行了更新。
问题1: 为什么有人会担心pyc不是最新的。
作为一个程序员来说,会有这样的担心是因为大多数程序的bug,常常是因为你获得的数据,并不是你想要的到的。
按道理来说,数据仅能有一个”发源地”,每次获取都要从发源地重新生成(就像是pyc
是py
的发源地)。但这很没效率,所以我们会做缓存文件。虽然缓存文件也有发源地,但生成之后便和发源地“没有任何瓜葛了”。
所以它并不能保证和”发源地”的数据同步,这样就会引发一系列问题。虽然在我们刚才的测试中,py
和pyc
不是这样的,但是另一些情况下就不同了。
比如在调试web程序的时候,常常会因为浏览器的缓存深受其害,比如你已经修改了某个地方,但是页面却没有显示到最新的。这会让你不知所措。
elisp
在 emacs中,你的所有扩展都是用elisp
来写的,这些文件以el
结尾。你可以指定自己的emacs如何去载入它们。
elisp
为了保证emacs有效率的载入el
文件,使用了类似于python
的pyc
文件,但是emacs并不自动生成这些字节码文件,需要你在emacs中使用命令去生成它们。
byte-compile-file
而且在emacs,即使你改变了el文件,emacs还是会优先去载入elc文件。
但在 emacs24.4中,加入了这样一个新的特性。load-prefer-newer
它能让你在载入一个模块的时候进行选择。如果这个变量被设置为t(rue)
,而且el
和elc
文件同时存在,并且你在代码中也没有指定哪个文件将被载入,那么emacs将优先载入较新的文件。
而默认的,这个变量的值为 nil
, 它只会载入elc
文件。
小插曲:
你会发现在python的例子中。只有foo文件才有自己的pyc
文件,bar文件并没有自己的pyc
文件,我想这是因为作为执行文件来说,要常常修改,本身不像库那样长久使用,所以没有必要为其生成一个pyc
字节码文件。
同样的,Emacser们把moudle类型的el
文件编译成elc
,而非脚本文件。