如何避免.pyc文件?

我可以运行python解释器而不生成编译后的.pyc文件吗?

139517 次浏览

据我所知,python会编译你“导入”的所有模块。然而,python不会编译使用"python script.py"运行的python脚本(它会编译脚本导入的任何模块)。

真正的问题是为什么你不想用python编译模块?如果它们碍事,你可能会自动清理它们。

对于运行Python解释器的用户,可以将模块所在的目录设置为只读。

我觉得没有比这更好的选择了。PEP 304似乎是试图为此引入一个简单的选项,但它似乎已被放弃。

我想,您可能正在尝试解决其他一些问题,对于这些问题,禁用.py[co]似乎是一种变通方法,但攻击这个原始问题可能会更好。

在2.5中,除了不给用户目录写权限之外,没有办法抑制它。

然而,在python 2.6和3.0中,sys模块中可能有一个名为“dont_write_bytecode”的设置可以设置为禁止这种情况。也可以通过传递"-B"选项来设置,或者设置环境变量"PYTHONDONTWRITEBYTECODE"

“Python 2.6新增功能-解释器更改”;:

Python现在可以阻止 编写.pyc或.pyo文件 将- b开关提供给Python 解释器,或通过设置 PYTHONDONTWRITEBYTECODE环境 变量,然后运行 翻译。此设置可用 到Python程序作为 sys.dont_write_bytecode变量,和 Python代码可以将值更改为

.修改解释器的行为

因此,以python -B prog.py的方式运行程序。

更新2010-11-27:Python 3.2通过引入特殊的__pycache__子文件夹(参见Python 3.2新增功能- PYC存储库目录)解决了源文件夹与.pyc文件混淆的问题。

注意:默认行为是生成字节码,是为了“performance"原因(更多信息请参见python2python3)。

实际上,在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文件,导入可能会相当慢。

因此,你所要做的就是压缩文件,将zip文件添加到你的sys。路径,然后导入。

如果你正在为UNIX构建这个脚本,你也可以考虑使用这个recipe: Unix压缩可执行文件来打包你的脚本,但请注意,如果你计划使用stdin或从sys。args(它可以做到没有太多的麻烦)。

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

import sys


sys.dont_write_bytecode = True

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

python LoginSuite.py

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

python -B LoginSuite.py

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

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

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

如果你自己用Python file作为参数启动Python,你可以指定-B:

python -B somefile.py

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

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

PYTHONDONTWRITEBYTECODE=x myutil

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

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

来自Python文档:

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

例子

如果你在Linux中的./profile中添加以下一行:

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

Python不会在你的项目目录中创建恼人的__pycache__目录,相反,它会把它们都放在~/.cache/cpython/