在生产中禁用 pyc 文件
Disabling pyc files in production
pyc
文件在过去一直是令人悲伤的原因,我最近看到一些关于防止 python 生成它们的帖子。目前我们只是 运行 一个脚本来在任何代码更改后清理它们以确保生成新的代码,但通常禁用它们会容易得多。在我们的生产环境中禁用它们是否有任何我可能不知道的副作用?这样做的缺点是什么?
我们遇到的唯一实际问题是文件有时会过时,导致导入错误,并且在大规模重构后难以调试。一旦意识到这是一个 pyc 问题,它就很容易修复,只需 运行 脚本,但在调试过程中可能需要 30 分钟才能实现。
您可以尝试将以下代码添加到您的 main.之后导入的任何模块都不会创建 .pyc:
import sys
sys.dont_write_bytecode=True
或设置环境变量:
PYTHONDONTWRITEBYTECODE
您还可以编辑或创建在 /site-packages
中找到的 usercustomize.py
以包含:
import sys
sys.dont_write_bytecode=True
也可以通过"-B"
选项。
就删除或禁用 .pyc 生成而言,影响似乎很小或无法区分。生成 .pyc 以提高速度。不是程序的速度,而是加载所需的时间。如果您经常 importing
一个模块,那么建议使用 .pyc,因为它可以减少所述模块的加载时间。经过研究,using/generating.pyc 似乎没有其他好处。
禁用编译字节码的编写和使用会在启动时产生性能成本——您的 Python 代码在进程生成时加载到内存中,非 .pyc/.pyo 文件意味着解释器在启动时被迫解析每个导入的文件。如果您当前正在从代码目录和导入中删除所有 .pyc 和 .pyo 文件,那么您已经在强制执行此版本。
我很好奇他们过去在什么地方引起了悲伤(你是否禁用文件系统上的修改时间?)好像 .py
文件比 .pyc
文件更新,Python 解释器(至少在常见的实现中,包括 CPython),将重新编译源代码,但这对于这个问题的范围来说并不是很重要。
如果您在函数后面导入,例如:
def my_database_call(budget_id):
import some_expensive_module_to_import
some_orm(...).get(budget_id)
在调用该函数之前不会产生导入成本(并且可能在以后的每一次调用中)。这与允许字节码(.pyc
或 "optimized" .pyo
文件)没有明显不同,但至少在那种情况下,你要为 import/parse/compile 付费价格只有一次。
如果你在评论中提出,如果你"shelling out"到OS调用Python脚本,并且不允许写入字节码该调用,每次调用都会产生编译价格。
pyc
文件在过去一直是令人悲伤的原因,我最近看到一些关于防止 python 生成它们的帖子。目前我们只是 运行 一个脚本来在任何代码更改后清理它们以确保生成新的代码,但通常禁用它们会容易得多。在我们的生产环境中禁用它们是否有任何我可能不知道的副作用?这样做的缺点是什么?
我们遇到的唯一实际问题是文件有时会过时,导致导入错误,并且在大规模重构后难以调试。一旦意识到这是一个 pyc 问题,它就很容易修复,只需 运行 脚本,但在调试过程中可能需要 30 分钟才能实现。
您可以尝试将以下代码添加到您的 main.之后导入的任何模块都不会创建 .pyc:
import sys
sys.dont_write_bytecode=True
或设置环境变量:
PYTHONDONTWRITEBYTECODE
您还可以编辑或创建在 /site-packages
中找到的 usercustomize.py
以包含:
import sys
sys.dont_write_bytecode=True
也可以通过"-B"
选项。
就删除或禁用 .pyc 生成而言,影响似乎很小或无法区分。生成 .pyc 以提高速度。不是程序的速度,而是加载所需的时间。如果您经常 importing
一个模块,那么建议使用 .pyc,因为它可以减少所述模块的加载时间。经过研究,using/generating.pyc 似乎没有其他好处。
禁用编译字节码的编写和使用会在启动时产生性能成本——您的 Python 代码在进程生成时加载到内存中,非 .pyc/.pyo 文件意味着解释器在启动时被迫解析每个导入的文件。如果您当前正在从代码目录和导入中删除所有 .pyc 和 .pyo 文件,那么您已经在强制执行此版本。
我很好奇他们过去在什么地方引起了悲伤(你是否禁用文件系统上的修改时间?)好像 .py
文件比 .pyc
文件更新,Python 解释器(至少在常见的实现中,包括 CPython),将重新编译源代码,但这对于这个问题的范围来说并不是很重要。
如果您在函数后面导入,例如:
def my_database_call(budget_id):
import some_expensive_module_to_import
some_orm(...).get(budget_id)
在调用该函数之前不会产生导入成本(并且可能在以后的每一次调用中)。这与允许字节码(.pyc
或 "optimized" .pyo
文件)没有明显不同,但至少在那种情况下,你要为 import/parse/compile 付费价格只有一次。
如果你在评论中提出,如果你"shelling out"到OS调用Python脚本,并且不允许写入字节码该调用,每次调用都会产生编译价格。