【问题标题】:How to avoid .pyc files?如何避免 .pyc 文件?
【发布时间】:2010-09-14 08:14:27
【问题描述】:

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

【问题讨论】:

    标签: python


    【解决方案1】:

    来自"What’s New in Python 2.6 - Interpreter Changes"

    现在可以防止 Python 编写 .pyc 或 .pyo 文件 为 Python 提供 -B 开关 解释器,或通过设置 PYTHONDONTWRITEBYTECODE环境 运行前的变量 口译员。此设置可用 将 Python 程序作为 sys.dont_write_bytecode 变量,和 Python代码可以将值更改为 修改解释器的行为。

    2010 年 11 月 27 日更新:Python 3.2 通过引入一个特殊的 __pycache__ 子文件夹解决了源文件夹与 .pyc 文件混淆的问题,请参阅 What's New in Python 3.2 - PYC Repository Directories

    注意:默认行为是生成字节码,并且出于“性能”原因而完成(有关更多信息,请参阅此处以获取 python2 并查看此处以获取 python3)。

    【讨论】:

    • 至少在运行 Python 2.7 的 OS X 10.8 上,环境变量不起作用。
    • 如果您要嵌入解释器(在 C++ 程序中),请使用“Py_DontWriteBytecodeFlag = 1;”在您的源代码中。这是在 pydebug.h 中声明的全局 int。
    • 环境变量在 2.7 中对我来说工作得很好,不知道其他人遇到了什么问题。谢谢!
    • 在 OSX(10.8 和 10.10)上也为我工作; @sorin 您是否正确导出了变量? export PYTHONDONTWRITEBYTECODE=1
    • 你知道如何用 pytest 做同样的事情吗?
    【解决方案2】:
    import sys
    
    sys.dont_write_bytecode = True
    

    【讨论】:

    • 我刚试过这个,它确实适用于导入的模块。具体来说,一旦设置了此变量,以后导入的任何内容都不会生成 pyc 文件。这是令人愉快的。谢谢。
    • 与其在父模块中添加,不如在引用的脚本中添加。这很酷。感谢@te wilson
    • 将此添加到您的site-packages/usercustomize.py 以使其适用于您的所有脚本。对我来说,这个目录是$HOME/.local/lib/python2.6/site-pacakges/usercustomize.py。参照。 docs.python.org/2/tutorial/…
    • 我的站点包位于:/usr/local/lib/python2.7/site-packages 我必须创建 usercustomize.py
    • 或单行:import sys; sys.dont_write_bytecode = True
    【解决方案3】:

    实际上在 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 executable,但请注意,如果您打算使用标准输入或从 sys.args 读取任何内容,您可能需要对此进行调整(可以轻松完成)。

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

    【讨论】:

      【解决方案4】:

      在 2.5 中,除了不授予用户对目录的写入权限等措施外,没有其他方法可以抑制它。

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

      【讨论】:

        【解决方案5】:

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

        来自 Python 文档:

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

        示例

        如果您在 Linux 中将以下行添加到您的 ./profile

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

        Python 不会在您的项目目录中创建烦人的 __pycache__ 目录,而是将它们全部放在 ~/.cache/cpython/

        【讨论】:

        • 我更愿意从我的目录和我的眼睛中删除这些数据,而不是避免使用已编译的代码:-)
        【解决方案6】:

        您可以在源代码中设置 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
        

        【讨论】:

          【解决方案7】:

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

          python LoginSuite.py
          

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

          python -B LoginSuite.py
          

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

          【讨论】:

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

            【讨论】:

              【解决方案9】:

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

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

              我想您可能正在尝试解决其他一些问题,禁用 .py[co] 似乎是一种解决方法,但最好还是解决这个原始问题。

              【讨论】:

                【解决方案10】:

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

                真正的问题是为什么您不希望 python 编译模块?如果它们妨碍您,您可能可以自动清理它们。

                【讨论】:

                • 我经常发现有陈旧的字节码.pyc文件。出于某种原因,当我更改类/模块时,.pyc 文件没有得到更新。所以当我修改.py文件后导入时,还是会使用.pyc文件,导致报错
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-04-30
                • 2016-07-24
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多