Выполнение скрипта Python изнутри virtualenv bin не работает

У меня есть сценарий, который я хочу быть доступным во всем мире. Я начал это со стандартного hashbang:

#! /usr/bin/env python

И связал его с каталогом bin моего virtualenv:

~/environments/project/env/bin/myscript

И добавил этот каталог в мой путь. Когда я запускаю команду:

myscript

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

Я исключил проблему с символьной ссылкой (я также попытался просто переместить скрипт в папку bin). Я также попытался запустить скрипт с Python

python ~/environments/project/env/bin/myscript

Ранее я использовал скрипт, который активировал среду, а затем запустил мой скрипт, но у меня сложилось впечатление, что скрипт, запускаемый из этой папки, должен запускаться с помощью интерпретатора virtualenv и пакетов сайта. Любые идеи о том, почему это может не сработать, или как я могу это отладить?

5 ответов

Решение

Помещение скрипта в корзину вашего virtualenv, а затем добавление этого местоположения в глобальный PATH не приведет к автоматическому получению вашего virtualenv. Вы должны сначала найти его, чтобы сделать его активным.

Все, что знает ваша система, - это проверить этот дополнительный путь к исполняемому файлу и запустить его. В этом сценарии нет ничего, что указывало бы на виртуальность.

Однако вы можете жестко закодировать строку she-bang в вашем python virtualenv, и в этом случае пакеты сайта окажутся на пути:

#!/Users/foo/environments/project/env/bin/python

Или другой вариант - просто создать крошечную оболочку bash, которая вызывает ваш оригинальный сценарий pythons, что позволит вам оставить свой оригинальный сценарий с общей самоуверенностью.

Так что если myscript.py это: #!/usr/bin/env python...

Тогда вы можете сделать myscript:

#!/bin/bash

/Users/foo/environments/project/env/bin/python myscript.py

Когда вы делаете myscript, он будет явно вызывать ваш скрипт на Python с установленным вами интерпретатором.

Я думаю, вы не понимаете, как работает virtualenv.

Короче говоря, virtualenv изменяет среду оболочки так, что Python будет искать в разных областях модули, которые вы хотите импортировать. На самом деле нет никакой связи между тем, где вы храните вашу виртуальную среду и где вы храните исходные файлы, которые вы запускаете в virtualenv. Если вы хотите, вы можете сохранить ваш virtualenv в каталоге ~/environment /my_env, а также весь исходный код, который вы кодируете при использовании virtualenv в ~/projects/my_proj.

Вы можете прочитать больше о том, что virtulenv делает в документах.

Действительно, единственное, что говорит Python, где искать модули, полностью основано на Python ( см. Документацию о том, как это работает). Активация virtualenv меняет способ работы python.

Вы можете вернуться к тому, чтобы скрипт оболочки активировал virtualenv для вас, или вы можете следовать этому рецепту, чтобы активировать его непосредственно из вашего скрипта.

activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

Если вы выбираете этот маршрут, имейте в виду информацию, которую дают документы:

Это изменит sys.path и даже изменит sys.prefix, но также позволит вам использовать существующий интерпретатор. Элементы в вашей среде будут отображаться сначала в sys.path, а не перед глобальными элементами. Однако глобальные элементы всегда будут доступны (как если бы при создании среды использовался флаг --system-site-packages, независимо от того, был он или нет). Кроме того, это не может отменить активацию других сред или импортированных модулей. Вы не должны пытаться, например, активировать среду перед веб-запросом; Вы должны активировать одну среду как можно раньше, и не делать это снова в этом процессе.

Не могли бы вы просто добавить относительный путь вместо этого? Это сработало для меня:

#!./env/bin/python

Если вы используете Windows, вы можете включить следующую строку в начало файла Python.

#! P:\Workspace\pythontut\Scripts python

Я столкнулся с той же проблемой и нашел это решение: https://github.com/jabbalaci/wpython. Это сценарий называетсяwpython"Это вызывает вашу программу с локальным интерпретатором Python в вашем venv. Таким образом, вместо"/Users/foo/environments/project/env/bin/python myscript.py"достаточно написать"wpython /path/to/myscript.pyMsgstr "Сценарий запуска может выглядеть так:

#!/usr/bin/env bash

cd /the/directory/where/myscript.py/is/located
wpython myscript.py
Другие вопросы по тегам