È possibile determinare se lo script corrente è in esecuzione all'interno di un ambiente virtualenv?
È possibile determinare se lo script corrente è in esecuzione all'interno di un ambiente virtualenv?
Risposte:
AFAIK il modo più affidabile per verificarlo (e il modo in cui viene utilizzato internamente in virtualenv e in pip) è verificare l'esistenza di sys.real_prefix:
import sys
if hasattr(sys, 'real_prefix'):
#...
All'interno di un virtualenv, sys.prefixpunta alla directory virtualenv, e sys.real_prefixindica il prefisso "reale" del sistema Python (spesso /usro /usr/localo qualcosa del genere).
Al di fuori di un virtualenv, sys.real_prefixnon dovrebbe esistere.
L'uso della VIRTUAL_ENVvariabile d'ambiente non è affidabile. È impostato dallo activatescript della shell virtualenv , ma un virtualenv può essere utilizzato senza attivazione eseguendo direttamente un eseguibile dalla directory bin/(o Scripts) di virtualenv , nel qual caso $VIRTUAL_ENVnon verrà impostato.
PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
Prova a usare pip -V(nota maiuscola V)
Se stai eseguendo l'env virtuale. mostrerà il percorso verso la posizione dell'ambiente.
virtualenvmolto, è possibile che questo possa fallire o mentirti. Se sta mentendo, puoi farlo find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+. Se fallisce (ho "dati di marshal cattivi") dovrai cancellare i file .pyc find /path/to/venv -type f -name "*.pyc" -exec rm {} \+(non preoccuparti, si ricostruiranno automaticamente).
...\lib\site-packagesin %PATH%. Quindi restituirà un falso positivo in quel caso.
Questo è un miglioramento della risposta accettata da Carl Meyer . Funziona con virtualenv per Python 3 e 2 e anche per il modulo venv in Python 3:
import sys
def is_venv():
return (hasattr(sys, 'real_prefix') or
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
Il controllo per le sys.real_prefixcopertine virtualenv, l'uguaglianza del non vuoto sys.base_prefixcon le sys.prefixcopertine venv.
Considera uno script che utilizza la funzione in questo modo:
if is_venv():
print('inside virtualenv or venv')
else:
print('outside virtualenv or venv')
E la seguente invocazione:
$ 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. Sto solo dicendo.
pipenvambienti virtuali creati.
Controlla la $VIRTUAL_ENVvariabile d'ambiente.
La $VIRTUAL_ENVvariabile di ambiente contiene la directory dell'ambiente virtuale quando si trova in un ambiente virtuale attivo.
>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'
Una volta eseguito deactivate/ abbandonato l'ambiente virtuale, la $VIRTUAL_ENVvariabile verrà cancellata / vuota. Python genererà a KeyErrorperché la variabile di ambiente non era impostata.
>>> 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'
Questi stessi controlli delle variabili d'ambiente possono ovviamente essere eseguiti anche al di fuori dello script Python, nella shell.
virtualenvvirtualenv che per venvvirtualenv.
Secondo virtualenv pep su http://www.python.org/dev/peps/pep-0405/#specification puoi semplicemente usare sys.prefix invece os.environ ['VIRTUAL_ENV'].
il sys.real_prefix non esiste nel mio virtualenv e lo stesso con il sys.base_prefix.
sys.real_prefix.
env |grep VIRTUAL_ENV |wc -l che restituirà un 1 se in un venv o uno 0 in caso contrario.
[[ -n $VIRTUAL_ENV ]] && echo virtualenvo in [[ -z $VIRTUAL_ENV ]] && echo not virtualenvbase alle tue esigenze.
Per verificare se il tuo Virtualenv interno:
import os
if os.getenv('VIRTUAL_ENV'):
print('Using Virtualenv')
else:
print('Not using Virtualenv')
Puoi anche ottenere più dati sul tuo ambiente:
import sys
import os
print(f'Python Executable: {sys.executable}')
print(f'Python Version: {sys.version}')
print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')
Ci sono molte buone risposte qui e alcune meno robuste. Ecco una panoramica.
Non fare affidamento sulla posizione di Python o sulla site-packagescartella.
Se questi sono impostati su posizioni non standard, ciò non significa che in realtà ti trovi in un ambiente virtuale. Gli utenti possono avere più di una versione di Python installata e quelli non sono sempre dove ti aspetti che siano.
Evita di guardare:
sys.executablesys.prefixpip -Vwhich pythonInoltre, non verificare la presenza di venv, .venvo envsin uno di questi percorsi. Ciò si interromperà per ambienti con una posizione più unica. Ad esempio,
Pipenv utilizza i valori hash come nome per i suoi ambienti.
VIRTUAL_ENV variabile d'ambienteEntrambi virtualenve venvimpostare la variabile di ambiente $VIRTUAL_ENVquando si attiva un ambiente. Vedi PEP 405 .
Puoi leggere questa variabile negli script di shell o usare questo codice Python per determinare se è impostato.
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"))
Il problema è che funziona solo quando l'ambiente è attivato dallo activatescript della shell.
Puoi avviare gli script dell'ambiente senza attivare l'ambiente , quindi se questo è un problema, devi usare un metodo diverso.
sys.base_prefixvirtualenv, venvE pyvenvpunto sys.prefixal Python installata all'interno del virtualenv come ci si aspetterebbe.
Allo stesso tempo, viene reso disponibile anche il valore originale di .sys.prefixsys.base_prefix
Possiamo usarlo per rilevare se siamo in 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_prefixOra attenzione, virtualenvprima che la versione 20 non fosse impostata sys.base_prefixma sys.real_prefixinvece fosse impostata .
Per sicurezza, controlla entrambi come suggerito nella risposta di 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
Se stai utilizzando ambienti virtuali Anaconda, controlla la risposta di Victoria Stuart .
running_in_virtualenv = sys.*base_*prefix != sys.prefix
if hasattr(sys, 'real_prefix'):test, che non funzionava più.
Uso abitualmente diversi ambienti virtuali (venv) installati su Anaconda. Questo frammento di codice / esempi consente di determinare se ci si trova in un venv (o nell'ambiente di sistema) e di richiedere anche un venv specifico per lo script.
Aggiungi allo script Python (frammento di codice):
# ----------------------------------------------------------------------------
# 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! ... ]
Esempio:
$ 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) $
Aggiornamento 1 - utilizzare negli script bash:
È inoltre possibile utilizzare questo approccio negli script bash (ad esempio, quelli che devono essere eseguiti in un ambiente virtuale specifico). Esempio (aggiunto allo script 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
Aggiornamento 2 [nov 2019]
Dal mio post originale sono passato da Anaconda Venv (e lo stesso Python ha evoluto ambienti virtuali Viz -a-Viz ).
Riesaminando questo problema, ecco un codice Python aggiornato che è possibile inserire per verificare che si stia operando in un ambiente virtuale Python specifico (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()
Ecco qualche codice esplicativo.
[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! :-)
>>>
Il modo più semplice è semplicemente eseguire which python:, se sei in virtualenv, punterà al suo pitone anziché a quello globale
(a cura) L'ho trovato in questo modo, cosa ne pensi? (restituisce anche il percorso di base venv e funziona anche per readthedocs dove il controllo della variabile env non lo fa):
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'] + '/../')
Ci sono già molti ottimi metodi pubblicati qui, ma aggiungo solo uno in più:
import site
site.getsitepackages()
ti dice dove sono pipinstallati i pacchetti.
site.getsitepackages()genera una directory che non è quella di sistema, puoi dedurre che ti trovi in un ambiente virtuale.
virtualenv.
venvstai usando.
Non è a prova di proiettile ma per ambienti UNIX test semplici come
if run("which python3").find("venv") == -1:
# something when not executed from venv
funziona benissimo per me. È più semplice quindi testare l'esistenza di alcuni attributi e, comunque, dovresti dare un nome alla tua directory venv venv.
Nel sistema operativo Windows vedi qualcosa del genere:
C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>
Le parentesi indicano che in realtà ci si trova nell'ambiente virtuale chiamato "virtualEnvName".
Una potenziale soluzione è:
os.access(sys.executable, os.W_OK)
Nel mio caso volevo solo scoprire se potevo installare gli oggetti con pip così com'è. Anche se potrebbe non essere la soluzione giusta per tutti i casi, considera semplicemente la verifica se disponi delle autorizzazioni di scrittura per l'ubicazione dell'eseguibile Python.
Nota: funziona in tutte le versioni di Python, ma restituisce anche Truese si esegue il sistema Python con sudo. Ecco un potenziale caso d'uso:
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'])
Questa è una vecchia domanda, ma troppi esempi sopra sono troppo complicati.
Keep It Simple: (nel terminale Jupyter Notebook o Python 3.7.1 su 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'
envsin quel percorso, questo smetterà di funzionare quando passi da anaconda a virtualenvo pipenv.