问题:如何避免.pyc文件?

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

Can I run the python interpreter without generating the compiled .pyc files?


回答 0

来自“ 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存储库目录中的新增功能

From “What’s New in Python 2.6 – Interpreter Changes”:

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.

Update 2010-11-27: Python 3.2 addresses the issue of cluttering source folders with .pyc files by introducing a special __pycache__ subfolder, see What’s New in Python 3.2 – PYC Repository Directories.


回答 1

import sys

sys.dont_write_bytecode = True
import sys

sys.dont_write_bytecode = True

回答 2

实际上,在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读取任何内容,则可能必须对其进行调整(可以做得没有太多麻烦)。

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

There actually IS a way to do it in Python 2.3+, but it’s a bit esoteric. I don’t know if you realize this, but you can do the following:

$ 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'

According to the zipimport library:

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.

Thus, all you have to do is zip the files up, add the zipfile to your sys.path and then import them.

If you’re building this for UNIX, you might also consider packaging your script using this recipe: unix zip executable, but note that you might have to tweak this if you plan on using stdin or reading anything from sys.args (it CAN be done without too much trouble).

In my experience performance doesn’t suffer too much because of this, but you should think twice before importing any very large modules this way.


回答 3

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

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

In 2.5, theres no way to suppress it, other than measures like not giving users write access to the directory.

In python 2.6 and 3.0 however, there may be a setting in the sys module called “dont_write_bytecode” that can be set to suppress this. This can also be set by passing the “-B” option, or setting the environment variable “PYTHONDONTWRITEBYTECODE”


回答 4

您可以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

You can set sys.dont_write_bytecode = True in your source, but that would have to be in the first python file loaded. If you execute python somefile.py then you will not get somefile.pyc.

When you install a utility using setup.py and entry_points= you will have set sys.dont_write_bytecode in the startup script. So you cannot rely on the “default” startup script generated by setuptools.

If you start Python with python file as argument yourself you can specify -B:

python -B somefile.py

somefile.pyc would not be generated anyway, but no .pyc files for other files imported too.

If you have some utility myutil and you cannot change that, it will not pass -B to the python interpreter. Just start it by setting the environment variable PYTHONDONTWRITEBYTECODE:

PYTHONDONTWRITEBYTECODE=x myutil

回答 5

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

python LoginSuite.py

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

python -B LoginSuite.py

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

I have several test cases in a test suite and before I was running the test suite in the Mac Terminal like this:

python LoginSuite.py

Running the command this way my directory was being populated with .pyc files. I tried the below stated method and it solved the issue:

python -B LoginSuite.py

This method works if you are importing test cases into the test suite and running the suite on the command line.


回答 6

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

从Python文档中:

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

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

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

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

Starting with Python 3.8 you can use the environment variable PYTHONPYCACHEPREFIX to define a cache directory for Python.

From the Python docs:

If this is set, Python will write .pyc files in a mirror directory tree at this path, instead of in pycache directories within the source tree. This is equivalent to specifying the -X pycache_prefix=PATH option.

Example

If you add the following line to your ./profile in Linux:

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

Python won’t create the annoying __pycache__ directories in your project directory, instead it will put all of them under ~/.cache/cpython/


回答 7

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

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

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

You could make the directories that your modules exist in read-only for the user that the Python interpreter is running as.

I don’t think there’s a more elegant option. PEP 304 appears to have been an attempt to introduce a simple option for this, but it appears to have been abandoned.

I imagine there’s probably some other problem you’re trying to solve, for which disabling .py[co] would appear to be a workaround, but it’ll probably be better to attack whatever this original problem is instead.


回答 8

解决方案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

Solution for ipython 6.2.1 using python 3.5.2 (Tested on Ubuntu 16.04 and Windows 10):

Ipython doesn’t respect %env PYTHONDONTWRITEBYTECODE =1 if set in the ipython interpretor or during startup in ~/.ipython/profile-default/startup/00-startup.ipy. Instead using the following in your ~.ipython/profile-default/startup/00-startup.py

import sys
sys.dont_write_bytecode=True

回答 9

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

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

As far as I know python will compile all modules you “import”. However python will NOT compile a python script run using: “python script.py” (it will however compile any modules that the script imports).

The real questions is why you don’t want python to compile the modules? You could probably automate a way of cleaning these up if they are getting in the way.


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。