开发者

How to execute another python script from your script and be able to debug?

You have wrapper python script that is calling another python script, currently using os.system('python another.py some-params').

You want to be able to debug both scripts and if you use os.system() you'll loose the debugger, so it does make sense to load the second script using the same interpretor instead of starting another one.

import doesn't to the expected thing because it does 开发者_JAVA技巧not run the __main__.

Other variants, like exec() or runpy seams to miss the argv parameters.

What solution do you see for this issue?

I'm looking for a solution that does not require you to modify the another.py script. Probably this will require to modify the sys.argv before executing it.


So far I found a solution that works only with Python 2.7+ (runpy.run_path() was introduced in Python 2.7).

If you can find one that works with 2.6 (or even 2.5) you are welcome to post it.

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


Do you have control over another.py? It would be a good idea to change it and add a main() method. Main() can then be invoked if __name__ == '__main__'. This will alleviate your problems a great deal. It is also unit testing friendly.


Based on the recommendation received from EOL, I made an extension to execfile() that does solve its limitations execfile2()

Below is the code, but newer versions will be published here. It is backwards compatible with 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


You can make the main block call a function. This way you will be able to call the same function when importing as a module.

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

if __name__ == "__main__":
    main()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜