Запустите python script с другого python script, передав в args

Я хочу запустить Python script из другого Python script. Я хочу передать переменные, как я бы использовал в командной строке.

Например, я бы запускал свой первый script, который перебирал бы список значений (0,1,2,3) и передавал их во второй script script2.py 0, затем script2.py 1 и т.д.

Я нашел SO 1186789, который является аналогичным вопросом, но ars отвечает на вызовы функции, где, поскольку я хочу запустить целую script не только функцию, а вызов balpha вызывает script, но без аргументов. Я изменил это на что-то вроде ниже в качестве теста:

execfile("script2.py 1")

Но он не принимает правильные значения. Когда я печатаю sys.argv в файле script2.py, это первоначальный командный вызов с первым script "['C:\script1.py'].

Я не хочу менять исходный script (т.е. script2.py в моем примере), так как я его не владею.

Я полагаю, что должен быть способ сделать это, я просто смущен, как вы это делаете.

Ответ 1

Попробуйте использовать os.system:

os.system("script2.py 1")

execfile отличается тем, что предназначен для запуска последовательности инструкций Python в текущем контексте выполнения. Вот почему sys.argv не изменился для вас.

Ответ 2

Это по своей сути неправильная вещь. Если вы используете Python script из другого Python script, вы должны общаться через Python, а не через ОС:

import script1

В идеальном мире вы можете напрямую вызвать функцию внутри script1:

for i in range(whatever):
    script1.some_function(i)

При необходимости вы можете взломать sys.argv. Там аккуратный способ сделать это с помощью диспетчера контекста, чтобы гарантировать, что вы не вносите никаких постоянных изменений.

import contextlib
@contextlib.contextmanager
def redirect_argv(num):
    sys._argv = sys.argv[:]
    sys.argv=[str(num)]
    yield
    sys.argv = sys._argv

with redirect_argv(1):
    print(sys.argv)

Я думаю, что это предпочтительнее передавать все ваши данные в ОС и обратно; это просто глупо.

Ответ 3

В идеале, Python script, который вы хотите запустить, будет настроен с кодом вроде этого ближе к концу:

def main(arg1, arg2, etc):
    # do whatever the script does


if __name__ == "__main__":
    main(sys.argv[1], sys.argv[2], sys.argv[3])

Другими словами, если модуль вызывается из командной строки, он анализирует параметры командной строки, а затем вызывает другую функцию main(), чтобы выполнить фактическую работу. (Фактические аргументы будут различаться, и синтаксический анализ может быть более задействован.)

Если вы хотите вызвать такой script из другого Python script, вы можете просто import его и вызвать modulename.main() напрямую, а не проходить через операционную систему.

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

Ответ 5

Я думаю, что хорошая практика может быть чем-то вроде этого;

import subprocess
cmd = 'python script.py'

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
out, err = p.communicate() 
result = out.split('\n')
for lin in result:
    if not lin.startswith('#'):
        print(lin)

согласно документации Модуль подпроцесса позволяет создавать новые процессы, подключаться к их каналам ввода/вывода/ошибок и получать коды возврата. Этот модуль намерен заменить несколько более старых модулей и функций:

os.system
os.spawn*
os.popen*
popen2.*
commands.*

Используйте функцию связи(), а не .stdin.write,.stdout.read или .stderr.read, чтобы избежать взаимоблокировок из-за того, что любой из других буферов буферов ОС заполняет и блокирует дочерний процесс. Читать здесь

Ответ 6

import subprocess
subprocess.call(" python script2.py 1", shell=True)