Skip to main content
 首页 » 编程设计

python之使用不同的脚本有效地重新执行 Python 解释器

2025年05月04日14myhome

我正在研究用 Python 编写的包装器脚本。包装器应该根据系统状态选择另一个 Python 脚本并执行它(使用绝对路径)。无需返回父脚本。

需要注意的是,我无法控制正在运行的脚本。他们可以使用 __name__ 检查,访问 sys.argv 并且它的所有行为都应该像直接运行脚本一样。

现在,我正在使用 os.execl():

import os, sys 
 
# ... 
 
os.execl(sys.executable, sys.executable, new_script, *sys.argv[1:]) 

但我至少可以算出三个问题:

<醇>
  • 传递给 Python 解释器的任何选项都不会保留(例如 python -v wrapper 在重新执行时不再冗长);
  • Python 解释器不必要地重新执行(使用 PyPy 它在我的系统上增加了 0.7s);
  • 它依赖于 sys.executable 有用,文档说:

    If Python is unable to retrieve the real path to its executable, sys.executable will be an empty string or None.

  • 我想知道我应该使用什么替换 os.execl 调用来解决所有问题。到目前为止,我可以说:

    1. execfile() 可能会工作,但它在 Python3 中被删除并手动重新实现它 AFAICS 很难看(因为编码问题)。我不确定 execfile() 还有什么其他含义;
    2. imp.load_module() 可能会工作,但它有点 hacky 并且在 Python3.3 中已被弃用。它可能也会遇到 Python3 编码问题。

    您建议我使用哪种解决方案?


    编辑:我会忘记的。该解决方案必须适用于 Python 2.5+、PyPy 和 Jython 2.5+。

    请您参考如下方法:

    我只会使用 execfile() 而不是 imp.load_module()。尽管控制权将返回到执行脚本,但一大优势是引用文档:

    It is different from the import statement in that it does not use the module administration — it reads the file unconditionally and does not create a new module.

    这意味着脚本文件可以在任何地方,可以有任何(或没有)文件扩展名,并且资源不会浪费在与模块导入相关的任务上。

    这样做会自动完成或避免您想要的事情:

    1. 将保留解释器选项
    2. 解释器不会在不必要的情况下重新执行
    3. 不依赖于sys.executable的值