如何避免.pyc文件?


268

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

Answers:


288

来自“ Python 2.6的新增功能-解释器更改”

现在,可以通过将-B开关提供给Python解释器,或者通过在运行解释器之前设置 PYTHONDONTWRITEBYTECODE环境变量来阻止Python编写.pyc或.pyo文件。此设置可作为Python程序的 sys.dont_write_bytecode变量使用,并且Python代码可以更改该值以修改解释程序的行为。

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


1
至少在运行Python 2.7的OS X 10.8上,环境变量无效。
索林2012年

5
如果要嵌入解释器(在C ++程序中),请使用“ Py_DontWriteBytecodeFlag = 1;”。在您的源代码中。这是在pydebug.h中声明的全局int。
JimB 2014年

1
环境变量在2.7中对我来说很好用,不知道其他人遇到了什么问题。谢谢!
2014年

8
在OSX(10.8和10.10)上也为我工作;@sorin是否正确导出了变量? export PYTHONDONTWRITEBYTECODE=1
nevelis 2014年

1
你知道如何用pytest做同样的事情吗?

110
import sys

sys.dont_write_bytecode = True

25
我刚刚尝试过,它确实适用于导入的模块。具体来说,一旦设置了此变量,以后导入的任何内容都不会生成pyc文件。这真令人愉快。谢谢。

与其在父模块中添加它,不如在引用的脚本中添加它。这很酷。感谢@te wilson
Sathy 2013年

4
将此添加到您的文件中,site-packages/usercustomize.py以使其适用于所有脚本。对我而言,该目录为$HOME/.local/lib/python2.6/site-pacakges/usercustomize.py。cf. docs.python.org/2/tutorial/...
ROBM

3
我的网站程序包位于:/usr/local/lib/python2.7/site-packages,我不得不创建usercustomize.py
anon58192932

3
或单行:import sys; sys.dont_write_bytecode = True
ET-CS

23

实际上,在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库:

ZIP档案中可能存在任何文件,但是只有.py和.py [co]文件可用于导入。不允许ZIP导入动态模块(.pyd,.so)。请注意,如果存档仅包含.py文件,Python将不会尝试通过添加相应的.pyc或.pyo文件来修改存档,这意味着,如果ZIP存档中不包含.pyc文件,则导入可能会相当缓慢。

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

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

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


11

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

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


7

您可以sys.dont_write_bytecode = True在源代码中进行设置,但这必须在第一个加载的python文件中。如果执行,python somefile.py则不会得到somefile.pyc

当您使用安装实用程序时setup.pyentry_points=您将sys.dont_write_bytecode在启动脚本中进行设置。因此,您不能依靠setuptools生成的“默认”启动脚本。

如果您自己以python文件作为参数启动Python,则可以指定-B

python -B somefile.py

somefile.pyc无论如何都不会生成,但是也不会.pyc导入其他文件的文件。

如果您具有某些实用程序myutil并且无法更改它,它将不会将-B传递给python解释器。只需通过设置环境变量来启动它PYTHONDONTWRITEBYTECODE

PYTHONDONTWRITEBYTECODE=x myutil

4

我在一个测试套件中有几个测试用例,在像这样在Mac Terminal中运行测试套件之前,我是这样的:

python LoginSuite.py

以这种方式运行命令,我的目录中填充了.pyc文件。我尝试了以下陈述的方法,它解决了问题:

python -B LoginSuite.py

如果要将测试用例导入测试套件并在命令行上运行套件,则此方法有效。


4

Python 3.8开始,您可以使用环境变量PYTHONPYCACHEPREFIX为Python定义一个缓存目录。

从Python文档中:

如果设置了该选项,Python将在此路径的镜像目录树中而不是源树中的pycache目录中写入.pyc文件。这等效于指定-X pycache_prefix = PATH选项。

如果./profile将以下行添加到Linux中:

export PYTHONPYCACHEPREFIX="$HOME/.cache/cpython/"

Python不会__pycache__在您的项目目录中创建恼人的目录,而是将所有这些目录置于~/.cache/cpython/


2

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

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

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


2

解决方案ipython 6.2.1 using python 3.5.2(在Ubuntu 16.04和Windows 10上测试):

Ipython不尊重%env PYTHONDONTWRITEBYTECODE =1是在ipython解释器中设置还是在中启动~/.ipython/profile-default/startup/00-startup.ipy。而是在您的~.ipython/profile-default/startup/00-startup.py

import sys
sys.dont_write_bytecode=True

0

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

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


我经常发现有过时的字​​节码.pyc文件。由于某种原因,当我更改类/模块时,.pyc文件不会更新。因此,当我在更改.py文件后导入它时,它仍然会使用该.pyc文件,从而导致错误
alpha_989 '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.