Как выполнить другой скрипт Python из вашего скрипта и иметь возможность отладки? - PullRequest
5 голосов
/ 07 сентября 2010

У вас есть скрипт Python-оболочки, который вызывает другой скрипт Python, в настоящее время использующий os.system('python another.py some-params').

. Вы хотите иметь возможность отлаживать оба сценария, и если вы используете os.system(), вы потеряете отладчик,поэтому имеет смысл загрузить второй скрипт, используя тот же интерпретатор, а не запускать другой.

import не соответствует ожидаемой вещи, потому что он не запускает __main__.

Другие варианты, такие как exec() или runpy швы для пропуска параметров argv.

Какое решение вы видите для этой проблемы?

Я ищу решениедля этого не требуется изменять скрипт another.py.Вероятно, для этого потребуется изменить sys.argv перед его выполнением.

Ответы [ 4 ]

6 голосов
/ 07 сентября 2010

До сих пор я нашел решение, которое работает только с 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
2 голосов
/ 09 сентября 2010

На основании рекомендации, полученной от 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
2 голосов
/ 07 сентября 2010

У вас есть контроль над another.py? Было бы неплохо изменить его и добавить метод main(). Main() может быть вызвано if __name__ == '__main__'. Это значительно облегчит ваши проблемы. Это также дружественное тестирование.

1 голос
/ 07 сентября 2010

Вы можете сделать так, чтобы основной блок вызывал функцию.Таким образом, вы сможете вызывать ту же функцию при импорте в виде модуля.

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

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