uWSGI 是不是使用预编译的 Python 文件?

Posted

技术标签:

【中文标题】uWSGI 是不是使用预编译的 Python 文件?【英文标题】:Does uWSGI use precompiled Python files?uWSGI 是否使用预编译的 Python 文件? 【发布时间】:2019-07-26 18:21:00 【问题描述】:

我正在使用 uWSGI 来部署我的 WSGI 应用程序。是为每个请求编译 Python 文件,还是预编译一次?我没有看到任何 .pyc 文件。

【问题讨论】:

【参考方案1】:

Python 缓存模块字节码 - 直接在 python2.x 的同一位置,在 python3 的 __pycache__ 子文件夹下 - 但脚本(不同之处在于用法 - 如果导入它是一个模块,如果你执行它是一个脚本)总是被重新编译(这就是为什么主脚本通常很短很简单)。

IOW,您的主 wsgi 脚本将为每个新的服务器进程重新编译一次。通常,一个 wsgi 应用程序作为一个长时间运行的进程,它将处理一个以上的请求,所以即使这样,初始编译开销也不是问题(短脚本 + 每个进程只编译一次)...

此外,一旦启动 Python 进程,导入的模块就会缓存在内存中,因此每个进程只会真正导入(加载)一次。

请注意,运行该进程的用户必须对您的应用目录具有写入权限才能创建 .pyc 文件...当然还有对 .pyc 文件的读取权限。

【讨论】:

我不是在质疑您答案的有效性,但您能否指出官方文档中描述了脚本行为的这种差异?我在PEP-3147 或Import. Cached Bytecode Invalidation 中没有找到任何相关信息 @AlexYu 至少在这里提到了这一点:docs.python.org/2/tutorial/modules.html#compiled-python-files,并且以稍微不同的方式,在这里:docs.python.org/3/tutorial/modules.html#compiled-python-files 谢谢!我在 python-2 的第一个链接中找到:“当通过在命令行上给出其名称来运行脚本时,脚本的字节码永远不会写入 .pyc 或 .pyo 文件””.这句话从python-3文档中去掉了,看起来很奇怪 @AlexYu 它已被替换为“它总是重新编译并且不存储直接从命令行加载的模块的结果”,这可能也是python -m modulename CLI 选项的原因。 非常感谢@bruno 和 Alex。现在,我知道为什么我的主脚本应该很小并且我应该导入模块以避免重复编译..【参考方案2】:

如果您使用CPython,那么默认情况下,它不会在每次收到请求时编译,除非您手动配置它来执行此操作。

通过第一个请求,uWSGI 将加载 python 脚本 bytecode 并将在我知道的 2 个不同场景中重新加载它:

    有一个之前没有加载过的新导入(只有新模块会被解析并转换为字节码)。 你明确地跑了service uwsgi restart

然而,仍然有一种方法可以通过解释器抑制它来继续在每个请求中重新加载 python 脚本,例如:python -B my_amazing_view.py

更多详情请看这里:

    What is pycache Should I generate .pyc

【讨论】:

这实际上有点复杂。 Python 运行时只编译(或者更准确地说,只缓存编译后的代码)模块,而不是脚本(实际上不同的是你是导入文件还是执行它)。 非常感谢先生,您的链接帮助很大。

以上是关于uWSGI 是不是使用预编译的 Python 文件?的主要内容,如果未能解决你的问题,请参考以下文章

C2653:不是没有预编译头文件的类或命名空间

预编译头文件 - 选择文件

在使用 github 操作进行构建期间执行诗歌安装时,使用预编译的 numpy 包而不是构建它

python+uwsgi导致redis无法长链接引起性能下降问题记录

我们是不是仍然需要为 NPM 预编译包而付出所有这些努力?

nginx+uwsgi+flask 服务器配置