从另一个 Python 脚本以优化模式运行 Python 脚本 [英] Running a Python script in optimized mode from another Python script
问题描述
有没有办法从另一个 Python (Python 3) 脚本以优化模式运行 Python 脚本?
Is there a way to run a python script in optimized mode from another Python (Python 3) script?
如果我有以下 test.py
脚本(它读取 内置常量__debug__
):
If I have the following test.py
script (which reads the built-in constant __debug__
):
if __debug__:
print('Debug ON')
else:
print('Debug OFF')
然后:
python text.py
打印Debug ON
python -OO text.py
打印Debug OFF
python text.py
printsDebug ON
python -OO text.py
printsDebug OFF
因为 常量 __debug__
作品:
because of how the constant __debug__
works:
如果 Python 没有以 -O
选项启动,则此常量为真.另请参阅 assert
语句.
This constant is true if Python was not started with an
-O
option. See also theassert
statement.
此外,__debug__
的值不能在运行时更改:__debug__
是一个常量,如文档 这里 和 此处.__debug__
的值在 Python 解释器启动时确定.
Also, the value of __debug__
cannot be changed at runtime: __debug__
is a constant, as noted in the documentation here and here. The value of __debug__
is determined when the Python interpreter starts.
以下正确打印Debug OFF
import subprocess
subprocess.run(["python", "-OO", "test.py"])
但是有没有更pythonic 的方式?如果解释器没有被称为 python
,上面的代码似乎不太便携.
But is there a more pythonic way?
The above doesn't seem very portable if the interpreter is not called python
.
我已经在这里和网上搜索过,但运气不佳.
I've already searched here and the web without luck.
推荐答案
使用 compile
我想出了一个使用内置函数的解决方案 <代码>编译,如下.
文件main.py
的内容:
with open('test.py') as f:
source_code = f.read()
compiled = compile(
source_code,
filename='test.py', mode='exec', optimize=2)
exec(compiled)
文件test.py
的内容:
if __debug__:
print('Debug ON')
else:
print('Debug OFF')
运行 python main.py
的输出是:
Debug OFF
参数optimize
的可能值:
-1
:使用与运行函数compile
的 Python 解释器相同的优化级别0
:没有优化,__debug__ == true
1
:类似-O
,即去掉assert
语句,__debug__ == false
立>2
:类似于-OO
,即也删除文档字符串.
-1
: use same optimization level as the Python interpreter that is running the functioncompile
0
: no optimization, and__debug__ == true
1
: like-O
, i.e., removesassert
statements, and__debug__ == false
2
: like-OO
, i.e., removes also docstrings.
不知道这是不是最好的选择,如果对他人有用就分享.
Don't know if it's the best option, just sharing if can be useful fo others.
基于 subprocess
的方法仍然更加简洁,并且可以通过使用 sys.executable
:
The subprocess
-based approach is still more concise, and can be made portable by using sys.executable
:
import subprocess
import sys
if not sys.executable:
raise RuntimeError(sys.executable)
proc = subprocess.run(
[sys.executable, '-OO', 'test.py'],
capture_output=True, text=True)
if proc.returncode != 0:
raise RuntimeError(proc.returncode)
以上代码调用函数subprocess.run
.
The above code calls the function subprocess.run
.
检查变量 sys.executable
的值是由 文档:
The check for the value of the variable sys.executable
is motivated by the documentation of CPython:
如果 Python 无法检索其可执行文件的真实路径,sys.executable
将为空字符串或 None
.
If Python is unable to retrieve the real path to its executable,
sys.executable
will be an empty string orNone
.
检查是用 raise
语句实现的,而不是 assert
语句,以检查上述 Python 代码本身是否在请求优化的情况下运行来自 Python,例如,通过使用 python -O
或 python -OO
或环境变量 PYTHONOPTIMIZE
.
The check is implemented with a raise
statement, instead of an assert
statement, in order to check also in cases that the above Python code is itself run with optimization requested from Python, e.g., by using python -O
or python -OO
or the environment variable PYTHONOPTIMIZE
.
使用 raise
语句还可以引发除 AssertionError
以外的异常,在本例中为 RuntimeError
.
Using raise
statements also enables raising an exception other than AssertionError
, in this case RuntimeError
.
对于运行在同一源文件中的函数内的 Python 代码(即在 main.py
内,而不是在 test.py
内),函数 inspect.getsource
可以使用,连同 option -c
的 >python
.
For running Python code that is within a function inside the same source file (i.e., inside main.py
, not inside test.py
), the function inspect.getsource
can be used, together with the option -c
of python
.
顺便说一句,欢迎提供更好的答案!
By the way better answers are welcome!
这篇关于从另一个 Python 脚本以优化模式运行 Python 脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!