Запуск подпроцесса в разных virtualenv с помощью python
Скажем, у меня есть две разные версии моего приложения, установленные в двух разных виртуальных средах. myapp v1.0 и myapp v2.0.
Теперь я хотел бы сравнить их. Сравнение написано на самом питоне. Какой был бы лучший способ сделать это? Предположим, что я могу запускать их отдельно, и оба записывают выходной файл, который я могу сравнить позже.
Один из способов сделать это - написать bash script (то, что у меня есть в настоящее время). Я активирую один virtualenv, запускаю myapp v1.0, активирую другой virtualenv, запускаю myapp v2.0. Затем запустите в этих файлах модуль сравнения. Но я хотел бы добавить там еще некоторую динамику (возьмем некоторые необязательные аргументы и т.д.), Что было бы проще с помощью python.
Edit:
В настоящее время у меня есть что-то вроде этого (bash script):
source virtualenv1/bin/activate
python my_script.py
deactivate
source virtualenv2/bin/activate
python my_other_script.py
deactivate
python my_comparison_script.py
вместо этого, я хотел бы сделать только:
python my_comparison_script.py
и мои скрипты будут запущены внутри этого.
Ответы
Ответ 1
что именно возникает? как использовать подпроцесс для выполнения команд оболочки? если в этом случае может возникнуть некоторый упрощенный псевдо-код:
import subprocess
myProcess = subprocess.Popen( ['these', 'are', 'for', 'the', 'shell'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE )
[outStream, errStream] = myProcess.communicate()
то вы можете делать все, что захотите, с помощью стандартного (outStream
) и делать разные вещи, если errStream
существует (стандартная ошибка). это включает в себя запись стандартной или стандартной ошибки в файл. то я предполагаю, что вы бы разбросали эти файлы?
фактический пример кода (предполагая, что у вас есть python 2.6+ в Linux-системе) может выглядеть так:
import subprocess
with open('dateHelp.log', 'w') as dateLog:
with open('dateHelp.err', 'w') as errLog:
dateHelp = subprocess.Popen([ 'date', '-h'], stdout=dateLog,
stderr=errLog)
dateHelp.communicate()
Ответ 2
Принятый ответ не решает проблему "активации" virtualenv в подпроцессе.
Если вы запускаете свое приложение с помощью вызова исполняемого файла python, как в вашем примере, это на самом деле очень просто: вам нужно только явно указать исполняемый файл в virtualenv.
import subprocess
subprocess.Popen(["virtualenv1/bin/python", "my_script.py"])
subprocess.Popen(["virtualenv2/bin/python", "my_other_script.py"])
запустит процессы в соответствующих virtualenvs.
Важный
Для решения проблем, озвученных в комментариях:
Если вы хотите запустить подпроцесс и обязательно использовать тот же интерпретатор, в котором выполняется текущий процесс, вы должны использовать sys.executable. Также доступно: sys.exec_prefix для доступа к префиксу каталога для конкретного сайта, где установлены зависящие от платформы файлы Python.
Если вы хотите более детально обсудить эту тему, взгляните на этот запрос.
Ответ 3
Простой вариант - запустить серию команд с подпроцессом следующим образом.
import subprocess
subprocess.call('source activate my_virtualenv; python my_script.py', shell=True)
И повторите по мере необходимости.
Ответ 4
Я думаю, что документация в virtualenv это хорошо объясняет.
TL; DR
Прямой запуск двоичного файла pyv для Venv НЕ похож на активацию venv. Вы также должны изменить переменные PATH и VIRTUAL_ENV соответственно (смотрите os.environ)
Источник
$ source/path/to/ENV/bin/activ
Это изменит ваш $ PATH, поэтому его первой записью будет каталог virtualenvs bin/. (Вы должны использовать источник, потому что он меняет вашу оболочку на месте.) Это все, что он делает; это чисто удобство.
Если вы напрямую запускаете скрипт или интерпретатор python из каталога bin/virtualenvs (например, путь/к /ENV/bin/pip или /path/to/ENV/bin/python-script.py), тогда sys.path автоматически будет установить использование библиотек Python, связанных с virtualenv. Но, в отличие от сценариев активации, переменные среды PATH и VIRTUAL_ENV не будут изменены. Это означает, что если ваш скрипт Python использует, например, подпроцесс для запуска другого скрипта Python (например, через строку шебанга Python!/Usr/bin/env), второй скрипт может не выполняться с тем же двоичным файлом Python, что и первый, и не иметь одинаковых библиотек. доступно для него. Чтобы этого не произошло, вашему первому сценарию необходимо будет изменить переменные среды таким же образом, как и сценарии активации, перед выполнением второго сценария.