Можно ли определить, работает ли текущий скрипт в среде virtualenv?
Можно ли определить, работает ли текущий скрипт в среде virtualenv?
Ответы:
AFAIK самый надежный способ проверить это (и способ, который используется внутренне в virtualenv и в pip) - это проверить наличие sys.real_prefix
:
import sys
if hasattr(sys, 'real_prefix'):
#...
Внутри virtualenv, sys.prefix
указывает на каталог virtualenv, и sys.real_prefix
указывает на «реальной» префиксом системы Python (часто /usr
или /usr/local
или некоторые такие).
Вне виртуальности sys.real_prefix
не должно существовать.
Использование VIRTUAL_ENV
переменной окружения ненадежно. Он устанавливается activate
сценарием оболочки virtualenv , но virtualenv можно использовать без активации, напрямую запустив исполняемый файл из каталога virtualenv bin/
(или Scripts
), в этом случае $VIRTUAL_ENV
он не будет установлен.
PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
Попробуйте использовать pip -V
(обратите внимание, заглавная V)
Если вы работаете в виртуальной среде. это покажет путь к местоположению env.
virtualenv
, возможно, это может не сработать или обманывать вас. Если он врет, вы можете сделать find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+
. Если это не удастся (я получил «неверные данные маршала»), вам нужно будет стереть файлы .pyc find /path/to/venv -type f -name "*.pyc" -exec rm {} \+
(не волнуйтесь, они восстановятся автоматически).
...\lib\site-packages
в %PATH%
. Таким образом, он вернет ложное срабатывание в этом случае.
Это улучшение принятого ответа Карла Мейера . Он работает с virtualenv для Python 3 и 2, а также для модуля venv в Python 3:
import sys
def is_venv():
return (hasattr(sys, 'real_prefix') or
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
Проверка на sys.real_prefix
обложки virtualenv, равенство непустых sys.base_prefix
с sys.prefix
обложками venv.
Рассмотрим скрипт, который использует такую функцию:
if is_venv():
print('inside virtualenv or venv')
else:
print('outside virtualenv or venv')
И следующий вызов:
$ python2 test.py
outside virtualenv or venv
$ python3 test.py
outside virtualenv or venv
$ python2 -m virtualenv virtualenv2
...
$ . virtualenv2/bin/activate
(virtualenv2) $ python test.py
inside virtualenv or venv
(virtualenv2) $ deactivate
$ python3 -m virtualenv virtualenv3
...
$ . virtualenv3/bin/activate
(virtualenv3) $ python test.py
inside virtualenv or venv
(virtualenv3) $ deactivate
$ python3 -m venv venv3
$ . venv3/bin/activate
(venv3) $ python test.py
inside virtualenv or venv
(venv3) $ deactivate
def is_venv(): return hasattr(sys, 'real_prefix') or sys.base_prefix != sys.prefix
. Просто говорю'.
pipenv
созданными виртуальными средами.
Проверьте $VIRTUAL_ENV
переменную среды.
$VIRTUAL_ENV
Переменная среды содержит каталог виртуальной среды, когда в активной виртуальной среде.
>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'
После запуска deactivate
/ выхода из виртуальной среды $VIRTUAL_ENV
переменная будет очищена / пуста. Python вызовет a, KeyError
потому что переменная окружения была не установлена.
>>> import os
>>> os.environ['VIRTUAL_ENV']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/os.py", line 678, in __getitem__
raise KeyError(key) from None
KeyError: 'VIRTUAL_ENV'
Те же самые проверки переменных среды, конечно же, можно выполнять и вне скрипта Python в оболочке.
virtualenv
virtualenv, так и для venv
virtualenv.
Согласно сообщению virtualenv на http://www.python.org/dev/peps/pep-0405/#specification вы можете просто использовать sys.prefix вместо os.environ ['VIRTUAL_ENV'].
sys.real_prefix не существует в моем virtualenv и не отличается от sys.base_prefix.
sys.real_prefix
.
env |grep VIRTUAL_ENV |wc -l
который вернет 1, если в venv, или 0, если нет.
[[ -n $VIRTUAL_ENV ]] && echo virtualenv
или в [[ -z $VIRTUAL_ENV ]] && echo not virtualenv
зависимости от ваших потребностей.
Чтобы проверить, есть ли у вас внутри Virtualenv:
import os
if os.getenv('VIRTUAL_ENV'):
print('Using Virtualenv')
else:
print('Not using Virtualenv')
Вы также можете получить больше данных о вашей среде:
import sys
import os
print(f'Python Executable: {sys.executable}')
print(f'Python Version: {sys.version}')
print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')
Здесь есть несколько хороших ответов, и некоторые менее надежные. Вот обзор.
Не полагайтесь на расположение Python или site-packages
папку.
Если они установлены в нестандартных местах, это не значит, что вы находитесь в виртуальной среде. Пользователи могут иметь более одной установленной версии Python, и это не всегда так, как вы ожидаете.
Избегайте смотреть на:
sys.executable
sys.prefix
pip -V
which python
Кроме того , не проверяют на наличие venv
, .venv
или envs
в любом из этих путей. Это сломается для сред с более уникальным местоположением. Например,
Pipenv использует хеш-значения в качестве имени для своей среды.
VIRTUAL_ENV
переменная окруженияОба virtualenv
и venv
установите переменную окружения $VIRTUAL_ENV
при активации окружения. Смотри PEP 405 .
Вы можете прочитать эту переменную в сценариях оболочки или использовать этот код Python, чтобы определить, установлена ли она.
import os
running_in_virtualenv = "VIRTUAL_ENV" in os.environ
# alternative ways to write this, also supporting the case where
# the variable is set but contains an empty string to indicate
# 'not in a virtual environment':
running_in_virtualenv = bool(os.environ.get("VIRTUAL_ENV"))
running_in_virtualenv = bool(os.getenv("VIRTUAL_ENV"))
Проблема заключается в том , что это работает только тогда , когда среда активируется с помощью activate
сценария оболочки.
Вы можете запустить сценарии среды не активируя ее , поэтому, если вас это беспокоит, вы должны использовать другой метод.
sys.base_prefix
virtualenv
, venv
И pyvenv
точка sys.prefix
в Python установлен внутри virtualenv , как можно было бы ожидать.
В то же время первоначальная стоимость sys.prefix
также доступна как sys.base_prefix
.
Мы можем использовать это, чтобы определить, находимся ли мы в virtualenv.
import sys
# note: Python versions before 3.3 don't have sys.base_prefix
# if you're not in virtual environment
running_in_virtualenv = sys.prefix != sys.base_prefix
sys.real_prefix
Теперь следите, virtualenv
до 20 версии не устанавливалиsys.base_prefix
а установилась sys.real_prefix
вместо этого.
Так что, чтобы быть в безопасности, проверьте оба, как предложено в ответе hroncok :
import sys
real_prefix = getattr(sys, "real_prefix", None)
base_prefix = getattr(sys, "base_prefix", sys.prefix)
running_in_virtualenv = (base_prefix or real_prefix) != sys.prefix
Если вы используете виртуальные среды Anaconda, проверьте ответ Виктории Стюарт .
running_in_virtualenv = sys.*base_*prefix != sys.prefix
if hasattr(sys, 'real_prefix'):
тест, который больше не работал.
Вы можете сделать which python
и посмотреть, если он указывает на тот, в виртуальной среде.
which
по умолчанию недоступно в Windows. Вы можете использовать where
вместо этого в Windows, или использовать whichcraft . Или посмотрите на sys.executable
. Но все же есть лучшие методы.
Я обычно использую несколько установленных Anaconda виртуальных сред (venv). Этот фрагмент кода / примеры позволяет вам определить, находитесь ли вы в venv (или в вашей системной среде), а также для запроса конкретного сценария venv.
Добавить в скрипт Python (фрагмент кода):
# ----------------------------------------------------------------------------
# Want script to run in Python 3.5 (has required installed OpenCV, imutils, ... packages):
import os
# First, see if we are in a conda venv { py27: Python 2.7 | py35: Python 3.5 | tf: TensorFlow | thee : Theano }
try:
os.environ["CONDA_DEFAULT_ENV"]
except KeyError:
print("\tPlease set the py35 { p3 | Python 3.5 } environment!\n")
exit()
# If we are in a conda venv, require the p3 venv:
if os.environ['CONDA_DEFAULT_ENV'] != "py35":
print("\tPlease set the py35 { p3 | Python 3.5 } environment!\n")
exit()
# See also:
# Python: Determine if running inside virtualenv
# http://stackoverflow.com/questions/1871549/python-determine-if-running-inside-virtualenv
# [ ... SNIP! ... ]
Пример:
$ p2
[Anaconda Python 2.7 venv (source activate py27)]
(py27) $ python webcam_.py
Please set the py35 { p3 | Python 3.5 } environment!
(py27) $ p3
[Anaconda Python 3.5 venv (source activate py35)]
(py35) $ python webcam.py -n50
current env: py35
processing (live): found 2 faces and 4 eyes in this frame
threaded OpenCV implementation
num_frames: 50
webcam -- approx. FPS: 18.59
Found 2 faces and 4 eyes!
(py35) $
Обновление 1 - используйте в скриптах bash:
Вы также можете использовать этот подход в скриптах bash (например, тех, которые должны работать в определенной виртуальной среде). Пример (добавлен в скрипт bash):
if [ $CONDA_DEFAULT_ENV ] ## << note the spaces (important in BASH)!
then
printf 'venv: operating in tf-env, proceed ...'
else
printf 'Note: must run this script in tf-env venv'
exit
fi
Обновление 2 [ноябрь 2019]
Со времени моего первоначального поста я перешел от Anaconda venv (и сам Python эволюционировал viz-a-viz виртуальные среды ).
Пересматривая эту проблему, вот обновленный код Python, который вы можете вставить, чтобы проверить, что вы работаете в определенной виртуальной среде Python (venv).
import os, re
try:
if re.search('py37', os.environ['VIRTUAL_ENV']):
pass
except KeyError:
print("\n\tPlease set the Python3 venv [alias: p3]!\n")
exit()
Вот некоторый пояснительный код.
[victoria@victoria ~]$ date; python --version
Thu 14 Nov 2019 11:27:02 AM PST
Python 3.8.0
[victoria@victoria ~]$ python
Python 3.8.0 (default, Oct 23 2019, 18:51:26)
[GCC 9.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, re
>>> re.search('py37', os.environ['VIRTUAL_ENV'])
<re.Match object; span=(20, 24), match='py37'>
>>> try:
... if re.search('py37', os.environ['VIRTUAL_ENV']):
... print('\n\tOperating in Python3 venv, please proceed! :-)')
... except KeyError:
... print("\n\tPlease set the Python3 venv [alias: p3]!\n")
...
Please set the Python3 venv [alias: p3]!
>>> [Ctrl-d]
now exiting EditableBufferInteractiveConsole...
[victoria@victoria ~]$ p3
[Python 3.7 venv (source activate py37)]
(py37) [victoria@victoria ~]$ python --version
Python 3.8.0
(py37) [victoria@victoria ~]$ env | grep -i virtual
VIRTUAL_ENV=/home/victoria/venv/py37
(py37) [victoria@victoria ~]$ python
Python 3.8.0 (default, Oct 23 2019, 18:51:26)
[GCC 9.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, re
>>> try:
... if re.search('py37', os.environ['VIRTUAL_ENV']):
... print('\n\tOperating in Python3 venv, please proceed! :-)')
... except KeyError:
... print("\n\tPlease set the Python3 venv [alias: p3]!\n")
...
Operating in Python3 venv, please proceed! :-)
>>>
Самый простой способ - просто запустить: which python
если вы в virtualenv, он будет указывать на свой питон вместо глобального
(отредактировано) Я нашел этот путь, что вы думаете об этом? (он также возвращает базовый путь venv и работает даже для readthedocs, где проверка переменной env не выполняется):
import os
import sys
from distutils.sysconfig import get_config_vars
def get_venv_basedir():
"""Returns the base directory of the virtualenv, useful to read configuration and plugins"""
exec_prefix = get_config_vars()['exec_prefix']
if hasattr(sys, 'real_prefix') is False or exec_prefix.startswith(sys.real_prefix):
raise EnvironmentError('You must be in a virtual environment')
return os.path.abspath(get_config_vars()['exec_prefix'] + '/../')
Здесь уже опубликовано много отличных методов, но добавим еще один:
import site
site.getsitepackages()
говорит вам, где pip
установлены пакеты.
site.getsitepackages()
выводит каталог, который не является системным, вы можете сделать вывод, что находитесь в виртуальной среде.
virtualenv
.
venv
вы используете.
Это не пуленепробиваемый, но для сред UNIX простой тест, такой как
if run("which python3").find("venv") == -1:
# something when not executed from venv
отлично работает для меня Это проще, чем тестировать существующий некоторый атрибут, и, в любом случае, вы должны назвать свой каталог venv venv
.
В ОС Windows вы видите что-то вроде этого:
C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>
Скобки означают, что вы на самом деле находитесь в виртуальной среде, называемой «virtualEnvName».
Потенциал решение:
os.access(sys.executable, os.W_OK)
В моем случае я просто хотел определить, могу ли я устанавливать элементы с помощью pip как есть. Хотя это может быть не правильным решением для всех случаев, попробуйте просто проверить, есть ли у вас разрешения на запись для расположения исполняемого файла Python.
Примечание: это работает во всех версиях Python, но также возвращается, True
если вы запускаете систему с Python sudo
. Вот потенциальный вариант использования:
import os, sys
can_install_pip_packages = os.access(sys.executable, os.W_OK)
if can_install_pip_packages:
import pip
pip.main(['install', 'mypackage'])
Это старый вопрос, но приведенные выше примеры слишком сложны.
Сохраняйте это простым: (в ноутбуке Jupyter или терминале Python 3.7.1 в Windows 10)
import sys
print(sys.executable)```
# example output: >> `C:\Anaconda3\envs\quantecon\python.exe`
OR
```sys.base_prefix```
# Example output: >> 'C:\\Anaconda3\\envs\\quantecon'
envs
в этом пути, это перестанет работать при переходе от анаконды к virtualenv
или pipenv
.