Запустите скрипт python из другого скрипта python, передав в args [дубликат]

этот вопрос уже есть ответ здесь:

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

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

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

execfile("script2.py 1")

но он не принимает переменные должным образом. Когда я распечатаю sys.argv in script2.py это исходный вызов команды для первого скрипта " ['C:script1.py'].

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

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

7 ответов


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

os.system("script2.py 1")

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


это по своей сути неправильно. Если вы используете скрипт Python из другого скрипта Python, вы должны общаться через 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)

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


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

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


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

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

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

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


подпроцесс module:
http://docs.python.org/dev/library/subprocess.html#using-the-subprocess-module

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

С этим вы также можете перенаправить stdin, stdout и stderr.


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

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.*

используйте communicate (), а не.стандартный ввод.писать. ,стандартный вывод.читать или. поток stderr.прочитайте, чтобы избежать блокировок из-за любого другого заполнения буферов ОС и блокирование дочернего процесса. Читать Здесь


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

Если ОС.система недостаточно мощная для вас, есть модуль подпроцесс.