Czy można ustalić, czy bieżący skrypt działa w środowisku virtualenv?
Czy można ustalić, czy bieżący skrypt działa w środowisku virtualenv?
Odpowiedzi:
AFAIK najbardziej niezawodnym sposobem sprawdzenia tego (i sposobem, który jest używany wewnętrznie w virtualenv i pip) jest sprawdzenie, czy istnieją sys.real_prefix
:
import sys
if hasattr(sys, 'real_prefix'):
#...
Wewnątrz virtualenv, sys.prefix
wskazuje katalog virtualenv i sys.real_prefix
wskazuje na „prawdziwe” prefiks systemu Pythona (często /usr
lub /usr/local
czy coś takiego).
Poza virtualenv sys.real_prefix
nie powinno istnieć.
Korzystanie ze VIRTUAL_ENV
zmiennej środowiskowej nie jest niezawodne. Jest ustawiony przez activate
skrypt powłoki virtualenv , ale virtualenv może być używany bez aktywacji poprzez bezpośrednie uruchomienie pliku wykonywalnego z katalogu bin/
(lub Scripts
) virtualenv , w którym to przypadku $VIRTUAL_ENV
nie zostanie ustawiony.
PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
Spróbuj użyć pip -V
(wypowiedz kapitał V)
Jeśli korzystasz z wirtualnej env. pokaże ścieżkę do lokalizacji środowiska.
virtualenv
często się poruszałeś , możliwe, że to się nie powiedzie lub okłamie. Jeśli kłamie, możesz to zrobić find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+
. Jeśli zawiedzie (mam „złe dane marszałka”), musisz wyczyścić pliki .pyc find /path/to/venv -type f -name "*.pyc" -exec rm {} \+
(nie martw się, odbudują się automatycznie).
...\lib\site-packages
w %PATH%
. W takim przypadku zwróci fałszywie dodatni wynik.
Jest to poprawka do zaakceptowanej odpowiedzi Carla Meyera . Działa z virtualenv dla Python 3 i 2, a także z modułem venv w Python 3:
import sys
def is_venv():
return (hasattr(sys, 'real_prefix') or
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
Sprawdzanie sys.real_prefix
okładek virtualenv, równość niepustych sys.base_prefix
z sys.prefix
coverami venv.
Rozważmy skrypt, który używa takiej funkcji:
if is_venv():
print('inside virtualenv or venv')
else:
print('outside virtualenv or venv')
I następujące wywołanie:
$ 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
. Tylko mówię'.
pipenv
utworzonych środowiskach wirtualnych.
Sprawdź $VIRTUAL_ENV
zmienną środowiskową.
$VIRTUAL_ENV
Zmienna zawiera katalog środowisku wirtualnym, gdy w aktywnym środowisku wirtualnym.
>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'
Po uruchomieniu deactivate
/ opuszczeniu środowiska wirtualnego $VIRTUAL_ENV
zmienna zostanie wyczyszczona / pusta. Python podniesie, KeyError
ponieważ zmienna środowiskowa została rozbrojona.
>>> 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'
Te same kontrole zmiennych środowiskowych można oczywiście również wykonać poza skryptem Pythona w powłoce.
virtualenv
virtualenv, jak i venv
virtualenv.
Według virtualenv pep na http://www.python.org/dev/peps/pep-0405/#specification możesz po prostu użyć sys.prefix zamiast os.environ ['VIRTUAL_ENV'].
sys.real_prefix nie istnieje w mojej virtualenv i to samo z sys.base_prefix.
sys.real_prefix
.
env |grep VIRTUAL_ENV |wc -l
która zwróci 1 jeśli w venv lub 0 jeśli nie.
[[ -n $VIRTUAL_ENV ]] && echo virtualenv
lub w [[ -z $VIRTUAL_ENV ]] && echo not virtualenv
zależności od potrzeb.
Aby sprawdzić, czy Twój wirtualny Virtualenv:
import os
if os.getenv('VIRTUAL_ENV'):
print('Using Virtualenv')
else:
print('Not using Virtualenv')
Możesz także uzyskać więcej danych o swoim środowisku:
import sys
import os
print(f'Python Executable: {sys.executable}')
print(f'Python Version: {sys.version}')
print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')
Jest tu wiele dobrych odpowiedzi i niektóre mniej niezawodne. Oto przegląd.
Nie polegaj na lokalizacji Pythona ani site-packages
folderu.
Jeśli są ustawione na niestandardowe lokalizacje, nie oznacza to, że faktycznie znajdujesz się w środowisku wirtualnym. Użytkownicy mogą mieć zainstalowaną więcej niż jedną wersję Pythona i nie zawsze są tam, gdzie się ich spodziewasz.
Unikaj patrzenia na:
sys.executable
sys.prefix
pip -V
which python
Nie należy również sprawdzić pod kątem obecności venv
, .venv
ani envs
w żadnym z tych ścieżek. To zepsuje się w środowiskach o bardziej unikalnej lokalizacji. Na przykład
Pipenv używa wartości skrótu jako nazwy swoich środowisk.
VIRTUAL_ENV
Zmienna środowiskowaZarówno virtualenv
i venv
ustaw zmienną środowiskową $VIRTUAL_ENV
podczas aktywacji środowiska. Zobacz PEP 405 .
Możesz odczytać tę zmienną w skryptach powłoki lub użyć tego kodu Python, aby ustalić, czy jest ustawiona.
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"))
Problem polega na tym, że działa to tylko wtedy, gdy środowisko jest aktywowane przez activate
skrypt powłoki.
Możesz uruchamiać skrypty środowiska bez aktywowania środowiska , więc jeśli jest to problem, musisz użyć innej metody.
sys.base_prefix
virtualenv
, venv
i pyvenv
wskaż sys.prefix
Python zainstalowany wewnątrz virtualenv, jak można się spodziewać.
Jednocześnie udostępniana jest również pierwotna wartość parametru .sys.prefix
sys.base_prefix
Możemy to wykorzystać do wykrycia, czy jesteśmy wirtualni.
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
Teraz uważaj, virtualenv
zanim wersja 20 nie ustawiła się, sys.base_prefix
ale ustawiła się sys.real_prefix
.
Aby być bezpiecznym, sprawdź oba, jak sugeruje odpowiedź 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
Jeśli używasz środowisk wirtualnych Anaconda, sprawdź odpowiedź Victorii Stuart .
running_in_virtualenv = sys.*base_*prefix != sys.prefix
if hasattr(sys, 'real_prefix'):
teście, który już nie działał.
Możesz to zrobić which python
i sprawdzić, czy wskazuje na to w wirtualnej env.
Rutynowo korzystam z kilku środowisk wirtualnych zainstalowanych przez Anacondę (venv). Ten fragment kodu / przykłady pozwala określić, czy jesteś w venv (lub środowisku systemowym), a także wymagać określonej venv dla skryptu.
Dodaj do skryptu Python (fragment kodu):
# ----------------------------------------------------------------------------
# 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! ... ]
Przykład:
$ 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) $
Aktualizacja 1 - użyj w skryptach bash:
Możesz także użyć tego podejścia w skryptach bash (np. Tych, które muszą działać w określonym środowisku wirtualnym). Przykład (dodany do skryptu 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
Aktualizacja 2 [lis 2019]
Od czasu mojego oryginalnego postu przeszedłem z Anaconda venv (a sam Python ewoluował w środowiskach wirtualnych viz-a-viz ).
Ponownie sprawdzając ten problem, oto zaktualizowany kod Pythona, który można wstawić w celu przetestowania działania w określonym środowisku wirtualnym 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()
Oto kod wyjaśniający.
[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! :-)
>>>
Najprościej jest po prostu uruchomić: which python
jeśli jesteś w virtualenv, wskaże on pytona zamiast globalnego
(edytowane) Znalazłem w ten sposób, co o tym sądzisz? (zwraca również ścieżkę bazową venv i działa nawet dla readthedocs, w których nie sprawdza się zmiennej 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'] + '/../')
Istnieje już wiele świetnych metod, ale wystarczy dodać jeszcze jedną:
import site
site.getsitepackages()
informuje, gdzie pip
zainstalowano pakiety.
site.getsitepackages()
wyprowadza katalog, który nie jest systemowy, możesz wywnioskować, że jesteś w środowisku wirtualnym.
virtualenv
.
venv
używasz.
To nie jest kuloodporny, ale dla środowisk UNIX prosty test jak
if run("which python3").find("venv") == -1:
# something when not executed from venv
działa dla mnie świetnie. To prostsze niż testowanie istnienia jakiegoś atrybutu, w każdym razie powinieneś nazwać swój katalog venv venv
.
W systemie operacyjnym Windows widać coś takiego:
C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>
Nawiasy oznaczają, że faktycznie znajdujesz się w środowisku wirtualnym o nazwie „virtualEnvName”.
Potencjalnym rozwiązaniem jest:
os.access(sys.executable, os.W_OK)
W moim przypadku naprawdę chciałem po prostu sprawdzić, czy mogę zainstalować elementy za pomocą pipa w takiej postaci, w jakiej są. Chociaż może to nie być właściwe rozwiązanie dla wszystkich przypadków, rozważ po prostu sprawdzenie, czy masz uprawnienia do zapisu dla lokalizacji pliku wykonywalnego Python.
Uwaga: działa to we wszystkich wersjach Pythona, ale zwraca również, True
jeśli uruchomisz systemowy Python sudo
. Oto potencjalny przypadek użycia:
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'])
To stare pytanie, ale zbyt wiele powyższych przykładów jest zbyt skomplikowanych.
Keep It Simple: (w Jupyter Notebook lub Python 3.7.1 terminal w systemie 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
na tej ścieżce, przestanie ona działać po przejściu z anakondy do virtualenv
lub pipenv
.