你有一个调用另一个python脚本的包装器python脚本,目前正在使用os.system('python another.py some-params')
。
您希望能够调试这两个脚本,如果您使用os.system()
,您将失去调试器,因此使用相同的解释器加载第二个脚本而不是启动另一个脚本是有意义的。
import
与预期不符,因为它不会运行__main__
。
其他变体,例如exec()
或runpy
接缝错过argv
参数。
您对此问题有何看法?
我正在寻找一种不需要您修改another.py
脚本的解决方案。可能需要在执行前修改sys.argv
。
答案 0 :(得分:6)
到目前为止,我发现了一个仅适用于Python 2.7+的解决方案(在Python 2.7中引入了runpy.run_path())。
如果您能找到适用于2.6(甚至2.5)的产品,欢迎您发布。
import runpy, sys
saved_argv = sys.argv
... # patch sys.argv[1:] and load new command line parameters
# run_path() does change only sys.argv[0] but restores it
runpy.run_path('another.py', run_name="__main__")
sys.argv = saved_argv # restore sys.argv
答案 1 :(得分:2)
您是否可以控制another.py
?更改它并添加main()
方法是个好主意。然后可以调用Main()
if __name__ == '__main__'
。这将大大缓解您的问题。它也是单元测试友好的。
答案 2 :(得分:2)
根据从EOL收到的建议,我对execfile()
进行了扩展,确实解决了其限制execfile2()
以下是代码,但新版本将发布here。它向后兼容execfile()
。
def execfile2(filename, _globals=dict(), _locals=dict(), cmd=None, quiet=False):
_globals['__name__']='__main__'
saved_argv = sys.argv # we save sys.argv
if cmd:
sys.argv=list([filename])
if isinstance(cmd , list):
sys.argv.append(cmd)
else:
sys.argv.extend(shlex.split(cmd))
exit_code = 0
try:
execfile(filename, _globals, _locals)
except SystemExit as e:
if isinstance(e.code , int):
exit_code = e.code # this could be 0 if you do sys.exit(0)
else:
exit_code = 1
except Exception:
if not quiet:
import traceback
traceback.print_exc(file=sys.stderr)
exit_code = 1
finally:
if cmd:
sys.argv = saved_argv # we restore sys.argv
return exit_code
答案 3 :(得分:1)
您可以将主块调用为函数。这样,您可以在导入模块时调用相同的函数。
def main():
print "All start up commands"
if __name__ == "__main__":
main()