【问题标题】:Running a Python script in optimized mode from another Python script从另一个 Python 脚本以优化模式运行 Python 脚本
【发布时间】:2020-09-14 19:18:56
【问题描述】:

有没有办法从另一个 Python (Python 3) 脚本以优化模式运行 Python 脚本?

如果我有以下test.py 脚本(读取built-in constant __debug__):

if __debug__:
    print('Debug ON')
else:
    print('Debug OFF')

然后:

  • python text.py 打印 Debug ON
  • python -OO text.py 打印 Debug OFF

因为constant __debug__ 的工作原理:

如果 Python 没有以 -O 选项启动,则此常量为真。另见assert 声明。

此外,__debug__ 的值不能在运行时更改:__debug__ 是一个常量,如文档herehere 中所述。 __debug__ 的值是在 Python 解释器启动时确定的。

以下正确打印 Debug OFF

import subprocess
subprocess.run(["python", "-OO", "test.py"])

但是有没有更多的 pythonic 方式? 如果解释器不被称为python,上述内容似乎不太便携。

我已经在这里和网上搜索过,但没有运气。

【问题讨论】:

标签: python python-3.x subprocess compiler-optimization assert


【解决方案1】:

使用compile

我想出了一个使用内置函数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 一样,也就是删除文档字符串。

不知道是不是最好的选择,如果对别人有用的话就分享一下吧。

使用subprocess.run

基于subprocess的方法还是更加简洁,可以使用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

检查变量sys.executable的值是由CPython的documentation推动的:

如果 Python 无法检索到其可执行文件的真实路径,sys.executable 将是一个空字符串或None

检查是使用raise 语句而不是assert 语句实现的,以便在上述Python 代码本身运行时使用Python 请求的优化,例如使用python -Opython -OO 或环境变量PYTHONOPTIMIZE

When optimization is requested, assert statements are removed.

使用raise 语句还可以引发AssertionError 以外的异常,在本例中为RuntimeError

对于在同一源文件内的函数内运行 Python 代码(即在 main.py 内,不在 test.py 内),可以使用函数 inspect.getsourceoption -c of python

顺便说一下,欢迎更好的答案!

【讨论】:

    猜你喜欢
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多