如何避免.pyc文件?

时间:2020-03-06 14:56:26  来源:igfitidea点击:

我可以在不生成编译的.pyc文件的情况下运行python解释器吗?

解决方案

据我所知,python将编译我们"导入"的所有模块。但是,python不会编译使用以下命令运行的python脚本:" python script.py"(但是它将编译该脚本导入的所有模块)。

真正的问题是为什么我们不希望python编译模块?如果它们阻碍了工作,我们可能会自动执行清理它们的方法。

我们可以将模块的目录以只读方式供运行Python解释器的用户使用。

我认为没有其他更优雅的选择。 PEP 304似乎试图为此引入一个简单的选项,但它似乎已被放弃。

我想我们可能正在尝试解决其他问题,对于这些问题,禁用.py [co]似乎是一种解决方法,但无论原始问题是什么,最好都进行攻击。

在2.5中,除了禁止用户对目录进行写访问之外,没有其他方法可以禁止它。

但是,在python 2.6和3.0中,sys模块中可能存在一个名为" dont_write_bytecode"的设置,可以对此设置进行抑制。也可以通过传递" -B"选项或者设置环境变量" PYTHONDONTWRITEBYTECODE"来进行设置

摘自" Python 2.6解释器更改的新增功能":

Python can now be prevented from
  writing .pyc or .pyo files by
  supplying the -B switch to the Python
  interpreter, or by setting the
  PYTHONDONTWRITEBYTECODE environment
  variable before running the
  interpreter. This setting is available
  to Python programs as the
  sys.dont_write_bytecode variable, and
  Python code can change the value to
  modify the interpreter’s behaviour.

2010年11月27日更新:Python 3.2通过引入特殊的__pycache__子文件夹解决了带有.pyc文件的源文件夹混乱的问题,请参阅Python 3.2 PYC存储库目录中的新增功能。

实际上,在Python 2.3+中有一种方法可以做到这一点,但这有点深奥。我不知道我们是否意识到了这一点,但是我们可以执行以下操作:

$ unzip -l /tmp/example.zip
 Archive:  /tmp/example.zip
   Length     Date   Time    Name
 --------    ----   ----    ----
     8467  11-26-02 22:30   jwzthreading.py
 --------                   -------
     8467                   1 file
$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32) 
>>> import sys
>>> sys.path.insert(0, '/tmp/example.zip')  # Add .zip file to front of path
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'

根据zipimport库:

Any files may be present in the ZIP archive, but only files .py and .py[co] are available for import. ZIP import of dynamic modules (.pyd, .so) is disallowed. Note that if an archive only contains .py files, Python will not attempt to modify the archive by adding the corresponding .pyc or .pyo file, meaning that if a ZIP archive doesn't contain .pyc files, importing may be rather slow.

因此,我们要做的就是将文件压缩,将压缩文件添加到sys.path中,然后导入它们。

如果要针对UNIX构建此脚本,则还可以考虑使用以下配方来打包脚本:unix zip可执行文件,但是请注意,如果我们打算使用stdin或者从sys.args中读取任何内容,则可能必须对其进行调整(可以做得没有太多麻烦)。

根据我的经验,性能不会因此受到太大影响,但是在以这种方式导入任何非常大的模块之前,我们应该三思而后行。