python解释器如何知道何时编译和更新.pyc文件?

WKP*_*lus 16 python

我知道一个.pyc文件是由python解释器生成的,并且包含字节代码,正如这个问题所说的那样.

我以为python解释器正在使用时间戳来检测a .pyc是否比a更新.py,如果是,则在执行时跳过再次编译.(makefile的做法)

所以,我做了一个测试,但似乎我错了.

  1. 我写了t.py包含print '123't1.py包含import t.运行命令python t1.py给出了输出123并生成了t.pyc所有内容.
  2. 然后我编辑t.pyprint '1234'和更新的时间戳 t.pyc使用touch t.pyc.
  3. 再跑python t1.py一次,我以为我会得到1231234 确实如此.所以似乎python解释器仍然知道t.py 更新.

然后我想知道python解释器是否会在t.pyc每次运行时编译和生成python t1.py.但是当我python t1.py多次运行时,我发现t.pyc未更新时t.py不会更新.

所以,我的问题是:python解释器如何知道何时编译和更新.pyc文件?

更新

由于python解释器使用存储在.pyc文件中的时间戳.我认为这.pyc是上次更新时间的记录.导入时,将其与.py文件的时间戳进行比较 .

所以我试图以这种方式破解它:将操作系统时间更改为较旧的时间,然后编辑.py文件.我想再次导入时,.py看起来比较旧.pyc,并且python解释器不会更新.pyc.但我又错了.

那么,python解释器是不是以较旧或较新的方式比较这两个时间戳,而是以完全相同的方式?

以完全相同的方式,我指的是.pyc记录中的时间戳,.py即上次修改的时间.导入时,它会将时间戳与当前时间戳进行比较.py,如果不相同,则重新编译和更新.pyc.

svv*_*vac 6

看起来时间戳直接存储在*.pyc文件中.python解释器不依赖于文件的最后修改属性,可能是为了避免在复制源树时出现不兼容的字节码问题.

查看语句的python实现import,您可以找到过时的签入_validate_bytecode_header().通过它的外观,它提取字节4到7(incl)并将其与源文件的时间码进行比较.如果那些不匹配,则字节码被视为停顿并因此重新编译.

在此过程中,它还会根据用于生成给定字节码的源的长度(存储在字节8到11中)检查源文件的长度.

在python实现中,如果其中一个检查失败,则字节码加载器引发一个ImportErrorcatched SourceLoader.get_code(),触发重新编译字节码.

注意:这就是在python版本中完成的importlib.我猜本机版本没有功能差异,但我的C有点太生疏了,无法深入研究编译器代码