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

时间:2012-11-17 10:12:57

标签: python

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

应该注意的是,我无法控制正在运行的脚本。他们可以使用__name__检查,访问sys.argv,如果脚本直接运行,它们的行为都应该如此。

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

import os, sys

# ...

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

但我至少可以解决三个问题:

  1. 不保留传递给Python解释器的任何选项(例如python -v wrapper在重新执行时停止冗长);
  2. Python解释器被不必要地重新执行(使用PyPy,它在我的系统上增加了0. 7);
  3. 它依赖sys.executable有用,文档说:

      

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

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

    1. execfile()可能会有效,但它已在Python3中删除并手动重新实现它AFAICS很难看(因为编码问题)。我不确定execfile()会有什么其他影响;
    2. imp.load_module()可能会有效,但它有点hacky并在Python3.3中被弃用。它也可能会遇到Python3编码问题。
    3. 您建议我使用哪种解决方案?


      编辑:我会忘记。解决方案必须使用Python 2.5 +,PyPy和Jython 2.5 +。

2 个答案:

答案 0 :(得分:1)

我只会使用execfile()代替imp.load_module()。虽然控制权将返回执行脚本,但一个很大的优点是,引用文档:

  

它与import语句的不同之处在于它不使用   模块管理 - 它无条件地读取文件而不是   创建一个新模块。

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

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

  1. 将保留解释器选项
  2. 解释器不会被不必要地重新执行
  3. 它不依赖于sys.executable
  4. 的值

答案 1 :(得分:-1)

你尝试过这样的事吗?

### wrapped script ###

import sys

print("__name__: {0}\nsys.argv: {1}".format(__name__, sys.argv))
### wrapper script ###

import builtins, sys

my_script = "wrapped_script.py"

print("Executing the wrapped script...")

sys.argv[0] = my_script
with open(my_script, 'r') as fd:
    for line in fd:
        exec(line)

结果:

$ python3 wrapped_script.py --foo --bar=quux
__name__: __main__
sys.argv: ['wrapped_script.py', '--foo', '--bar=quux']

$ python3 wrapper.py --foo --bar=quux
Executing the wrapped script...
__name__: __main__
sys.argv: ['wrapped_script.py', '--foo', '--bar=quux']