经过一段时间在这里寻找重复项后,我发现唯一的事情是无操作并使用 Cython 进行优化,这是完全不相关的。我想要完成的是动态设置python -O
运行时标记.
基本上,有一个值sys.flags.optimize
这是只读的。我正在寻找一个选项来更改它或找到一个可以更改该值并影响字节码生成的位置。
根据doc https://docs.python.org/3/tutorial/modules.html#compiled-python-files官方方法是在解释器启动之前调用它,所以我想知道这是否可能,但这就是我发现的:
- Python/compiler.c -> c_optimize https://github.com/python/cpython/blob/99b54d68172ad64ba3d0fdc0137f0df88c28ea2b/Python/compile.c#L161
-
optimization_level https://github.com/python/cpython/blob/8462a4936b3a551dc546a6adea04a70b0a07ca67/Python/initconfig.c#L1251通过环境变量在 C 中设置
PYTHONOPTIMIZE
- Lib/py_compile.py https://github.com/python/cpython/blob/2e33ecd7c9b0cac3efc6fcbdd4547fd086b4e2d1/Lib/py_compile.py#L79
这看起来像py_compile
被称为“某处”(GitHub 搜索仅显示文档或测试,而不是运行时的实际调用者)并管理optimization_level
in the compiler.c
从上面。这意味着我可以在 Python 中更改它,并让编译的解释器在同一会话/进程中对经过或不经过优化的代码进行汇编。
我似乎找不到 CLI 参数解析,也找不到任何可以在运行时更改的相关“状态”。
我的目标(目前)是选择性地允许/删除assert
可以通过以下方式完成关键字-O
单独(通过compiler_assert() https://github.com/python/cpython/blob/99b54d68172ad64ba3d0fdc0137f0df88c28ea2b/Python/compile.c#L3256需要级别集,但是我正在努力寻找构建 AST 的 C 代码和似乎保持配置状态的实际 Python 代码之间的“缺失链接”(因为py_compile
含有原料optimize
值)并且似乎正在为解释器本身编译和加载字节码。
有什么办法可以改变optimization_level
这样我就可以实现这种行为并且几乎可以在单个 Python 会话中完成此操作?
>>> # change optimize to 1
>>> def test(): assert True
>>> import dis
>>> dis.dis(test)
1 0 LOAD_CONST 0 (None)
2 RETURN_VALUE
>>> # change optimize to 0
>>> dis.dis(test)
1 0 LOAD_CONST 1 (True)
2 POP_JUMP_IF_TRUE 8
4 LOAD_GLOBAL 0 (AssertionError)
6 RAISE_VARARGS 1
>> 8 LOAD_CONST 0 (None)
10 RETURN_VALUE