我可以运行python解释器而不生成编译后的.pyc文件吗?
据我所知,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现在可以阻止 编写.pyc或.pyo文件 将- b开关提供给Python 解释器,或通过设置 PYTHONDONTWRITEBYTECODE环境 变量,然后运行 翻译。此设置可用 到Python程序作为 sys.dont_write_bytecode变量,和 Python代码可以将值更改为
sys.dont_write_bytecode
因此,以python -B prog.py的方式运行程序。
python -B prog.py
更新2010-11-27:Python 3.2通过引入特殊的__pycache__子文件夹(参见Python 3.2新增功能- PYC存储库目录)解决了源文件夹与.pyc文件混淆的问题。
__pycache__
.pyc
PYTHONDONTWRITEBYTECODE=1
实际上,在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。
sys.dont_write_bytecode = True
python somefile.py
somefile.pyc
当你使用setup.py和entry_points=安装一个实用程序时,你将在启动脚本中设置sys.dont_write_bytecode。因此,您不能依赖setuptools生成的“默认”启动脚本。
setup.py
entry_points=
如果你自己用Python file作为参数启动Python,你可以指定-B:
-B
python -B somefile.py
无论如何,somefile.pyc都不会生成,但其他导入的文件也不会生成.pyc文件。
如果你有一些实用程序myutil并且你不能改变它,它将不会将-B传递给python解释器。只需通过设置环境变量PYTHONDONTWRITEBYTECODE来启动它:
myutil
PYTHONDONTWRITEBYTECODE
PYTHONDONTWRITEBYTECODE=x myutil
ipython 6.2.1 using python 3.5.2的解决方案(在Ubuntu 16.04和Windows 10上测试):
ipython 6.2.1 using python 3.5.2
Ipython不尊重%env PYTHONDONTWRITEBYTECODE =1,如果在ipython解释器中设置或在~/.ipython/profile-default/startup/00-startup.ipy启动时设置。 相反,在~.ipython/profile-default/startup/00-startup.py
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定义缓存目录。
PYTHONPYCACHEPREFIX
来自Python文档:
如果设置了该值,Python将在镜像目录树的此路径下写入.pyc文件,而不是在源树的pycache目录中。这相当于指定-X pycache_prefix=PATH选项。
例子
如果你在Linux中的./profile中添加以下一行:
./profile
export PYTHONPYCACHEPREFIX="$HOME/.cache/cpython/"
Python不会在你的项目目录中创建恼人的__pycache__目录,相反,它会把它们都放在~/.cache/cpython/下
~/.cache/cpython/