11

你有一个包装 python 脚本,它正在调用另一个 python 脚本,当前使用os.system('python another.py some-params').

您希望能够调试这两个脚本,如果您使用os.system(),您将失去调试器,因此使用相同的解释器加载第二个脚本而不是启动另一个脚本是有意义的。

import没有达到预期的效果,因为它没有运行__main__.

其他变体,例如exec()runpy接缝以错过argv参数。

你认为这个问题有什么解决方案?

我正在寻找不需要您修改another.py脚本的解决方案。可能这需要sys.argv在执行之前修改它。

4

4 回答 4

9

到目前为止,我找到了一个仅适用于 Python 2.7+ 的解决方案(runpy.run_path() 是在 Python 2.7 中引入的)。

如果您能找到适用于 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
于 2010-09-07T13:19:53.767 回答
2

根据从 EOL 收到的建议,我做了一个扩展execfile(),确实解决了它的限制execfile2()

下面是代码,但更新的版本会在这里发布。它向后兼容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
于 2010-09-09T11:48:29.107 回答
2

你有控制权another.py吗?更改它并添加一个main()方法是个好主意。Main()然后可以调用if __name__ == '__main__'。这将大大减轻您的问题。它也是单元测试友好的。

于 2010-09-07T10:59:57.237 回答
1

您可以使主块调用一个函数。这样,您将能够在作为模块导入时调用相同的函数。

def main():
    print "All start up commands"

if __name__ == "__main__":
    main()
于 2010-09-07T11:01:03.847 回答