2

我正在研究用 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,7s);
  3. 它依赖于sys.executable有用,文档说:

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

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

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

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


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

4

2 回答 2

1

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

它与 import 语句的不同之处在于它不使用模块管理——它无条件地读取文件并且不创建新模块。

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

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

  1. 解释器选项将被保留
  2. 解释器不会被不必要地重新执行
  3. 它不依赖于sys.executable
于 2012-11-18T23:06:34.580 回答
-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']
于 2012-11-17T17:18:43.767 回答