Posso spostare un virtualenv?


93

Questa domanda non è un duplicato.

Riguarda non solo la ridenominazione di un ambiente virtuale, ma lo spostamento effettivamente in una directory diversa, inclusa, potenzialmente, una directory utente diversa.

Non è la stessa cosa che rinominare semplicemente un ambiente virtuale, specialmente per le persone che non hanno familiarità con i virtualenvs.

Se creo un virtualenv e lo sposto in una cartella diversa, funzionerà ancora?

$ virtualenv -p /usr/bin/python3 /home/me/Env/my-python-venv
$ source Env/my-python-venv/bin/activate
(my-python-venv) $ 

... più tardi quel giorno, l'ambiente virtuale si trasferì ...

(my-python-venv) $ deactivate
$ mkdir -p /home/me/PeskyPartyPEnvs
$ mv /home/me/Env/my-python-venv /home/me/PeskyPartyPEnvs/

Domanda:

Funzionerà?

$ source /home/me/PeskyPartyPEnvs/my-python-venv/bin/activate
(my-python-venv) $ /home/me/PeskyPartyPEnvs/my-python-venv/bin/pip3 install foaas

Intendo questo meno come una domanda sulla saggezza di provare questo (a meno che questa saggezza non sia divertente, ovviamente) e più sul fatto che sia possibile. Voglio davvero sapere se è possibile farlo in Python 3 o se devo solo succhiarlo e clonarlo.

Posso solo mvun virtualenvgenere senza tristezza? Voglio evitare la tristezza.

Risposte:


70

Sì. È possibile spostarlo sulla stessa piattaforma. È possibile utilizzare --relocatablein un ambiente esistente.

Da --help:

--relocatable - Rende un ambiente virtualenv ESISTENTE rilocabile. Questo risolve gli script e rende relativi tutti i file .pth.

TUTTAVIA, questo NON sembra cambiare lo activatescript, ma piuttosto cambia solo gli script pip*e easy_install*. Nello activatescript, la $VIRTUAL_ENVvariabile di ambiente codificata come l'originale /path/to/original/venv. La $VIRTUAL_ENVvariabile viene utilizzata anche per impostare il PATHtuo ambiente attivo, quindi deve essere modificata in base alla nuova posizione per poter chiamare pythone così pipvia senza percorso assoluto.

Per risolvere questo problema, puoi modificare la $VIRTUAL_ENVvariabile di ambiente nello activatescript (ad esempio utilizzando sed) e tutto dovrebbe essere a posto.

Un esempio di utilizzo:

$ cd ~/first
$ virtualenv my-venv
$ grep 'VIRTUAL_ENV=' my-venv/bin/activate
VIRTUAL_ENV="/home/username/first/my-venv"
$ virtualenv --relocatable my-venv
Making script my-venv/bin/easy_install relative
Making script my-venv/bin/easy_install-2.7 relative
Making script my-venv/bin/pip relative
Making script my-venv/bin/pip2 relative
Making script my-venv/bin/pip2.7 relative
### Note that `activate` has not been touched
$ mkdir ~/second
$ mv my-venv ~/second
$ cd ~/second
$ grep 'VIRTUAL_ENV=' my-venv/bin/activate
VIRTUAL_ENV=/home/username/first/my-venv
### (This variable hasn't been changed, it still refers to the old, now non-existent directory!)
$ sed -i -e 's|username/first|username/second|' my-venv/bin/activate
## sed can be used to change the path.
## Note that the `-i` (in place) flag won't work on all machines. 
$ source my-venv/bin/activate 
(my-venv) $ pip install foass
...
(my-venv) $ python 
[...]
> import foass

Evviva, ora puoi installare le cose e caricarle nel tuo ambiente virtuale appena individuato.


//, Hm. Questo non sembra effettivamente finire per renderli trasferibili. Continuo a ricevere qualche errore perché non sono file di script "normali".
Nathan Basanese

7
"L'opzione --relocatable attualmente presenta una serie di problemi e non è garantito che funzioni in tutte le circostanze. È possibile che l'opzione sarà deprecata in una versione futura di virtualenv. " (Enfasi mia) vedere la guida dell'utente
BobTuckerman

1
L'ho provato su Windows e l'errore elenca tutti gli script (* .py, * .bat, * .ps1) nella Scriptsdirectory (equivalente a bin* nix) e dice qualcosa come activate.ps1 cannot be made relative (it's not a normal script that starts with #!c:\..python.exe.fondamentalmente si lamenta che l'hash-bang nel file header non è l'attuale python.exe di virtualenv, è quello da cui l'ho spostato -easy fixed. Ho guardato in quel copione elegante e comunque scopre già il suo percorso - bello. Anche alcuni degli altri script non si basano su percorsi (ad es. Disattivare.bat) quindi, in breve, funziona.
Davos

2
@NathanBasanese il messaggio activate.ps1 cannot be made relativepuò essere ignorato perché quello script è già relativo. Il messaggio non è utile in Windows, perché gli script non usano le #!direttive come in Linux per dire alla shell quale applicazione dovrebbe eseguirlo. Il activate.batnon viene modificato, ma non viene utilizzato (almeno su Windows 10, chiamando activateavvia lo script PoSH) quindi no non ho bisogno di modificare alcuno script. Il problema è pip.exeche ha un percorso per Python hard-coded e deve essere modificato con un editor esadecimale o semplicemente una reinstallazione.
Davos

3
@Sgedda In retrospettiva direi di non farlo. I tuoi ambienti python dovrebbero essere facilmente ricreabili utilizzando almeno pip freezeun file dei requisiti in modo da poter reinstallare facilmente tutti i tuoi pacchetti, docker (funziona bene con virtualenv installato su di esso), conda, pyenv o alcuni altri strumenti. Dovresti essere in grado di creare e distruggere ambienti come infrastrutture immutabili, non dovrebbero essere preziosi.
Davos

19

Per Python 3.3+ (con nuovo venvmodulo integrato)

Risposta breve (indipendentemente dalla versione):

  • Non esiste un modo pulito e diretto per spostare un ambiente virtuale
  • Basta ricreare, è facile !!


Risposta lunga:

A partire da Python v3.3, virtualenvè diventato un modulo integrato denominato venv.

L' --relocatableopzione menzionata in altre risposte non è stata inclusa venve al momento non esiste un modo valido e sicuro di cui sono a conoscenza per rinominare o riposizionare un ambiente virtuale Python.

Tuttavia, esiste un modo abbastanza semplice per ricreare semplicemente un ambiente virtuale, con tutti i suoi pacchetti attualmente installati. Vedere questa risposta o consultare la sezione seguente per informazioni sulla creazione di un ambiente virtuale. Durante il processo puoi ricreare il nuovo ambiente in qualsiasi luogo e con qualsiasi nome desideri. Oppure vedere la sezione seguente per il processo.

In quella risposta, menziona alcuni altri pacchetti di terze parti che possono supportare ridenominazioni o spostamenti diretti. Se sei deciso a perseguire un modo per spostare intatto un ambiente virtuale, potresti esaminare se funzionano anche con venvquelli.

Nota: in quella risposta, è focalizzato su virtualenv, piuttosto che venv. Vedi sotto per come tradurre.



venvrispetto alla virtualenvsintassi dei comandi precedente

Il comando da usare venvè:

python -m venv

piuttosto che solo virtualenv, che si installa come comando nel pacchetto originale. Dove "python" si riferisce a come esegui il tuo eseguibile python, che potrebbe essere una varietà di cose, come ad esempio:

  1. python
  2. pyo py -3.7o simili (il Python Launcher per Windows per Python 3.3+ e Windows solo al momento)
  3. python3 (convenzione per ambienti Linux che installano due volte python 2 e 3)
  4. In caso di problemi, utilizzare il percorso assoluto dell'eseguibile Python che si desidera eseguire: ad es c:\program files\python37\python.exe

Se non sei sicuro di quale versione sia in esecuzione, puoi sempre python --versionscoprirlo.



Come ricreare un ambiente virtuale

Creare / ricreare un ambiente virtuale è facile e dovrebbe diventare una seconda natura dopo aver lavorato un po 'con loro. Questo processo rispecchia quello che faresti per distribuire il tuo script come pacchetto (con le sue dipendenze) nella prima metà, e poi cosa farebbe qualcuno per installare il tuo script / pacchetto per un ulteriore sviluppo.

Per prima cosa, ottieni un elenco aggiornato di ciò che è nell'ambiente virtuale. Con esso attivo, ottieni la versione di Python che usa e salva l'elenco delle dipendenze in un file.

  1. Utilizzare python --versioncon l'ambiente virtuale attivato per vedere quale versione di Python sta utilizzando.

    • Questo è per chiarezza: potresti voler aggiornare la versione di Python per vari motivi, almeno all'ultima versione della patch
    • Ad esempio, se il venv esistente utilizza Python v3.7.4, ma ora la v3.7.6 non è disponibile, utilizza invece la v3.7.6, che dovrebbe includere solo sicurezza senza interruzioni e correzioni di bug.
  2. Utilizzare python -m pip freeze > requirements.txtper creare l'elenco delle dipendenze del pacchetto corrente e inserirle nel requirements.txtfile. Questo comando funziona sicuramente in Linux o Git Bash, non sicuro al 100% su Powershell o riga di comando in Windows.

Ora crea un nuovo ambiente virtuale e poi aggiungi le dipendenze da quello vecchio.

  1. Crea il tuo nuovo venv.

    • Assicurati di utilizzare la versione corretta di python che desideri installare su venv.
    • Se vuoi che sia esattamente la stessa versione di Python:
      • Esegui python direttamente dall'ambiente virtuale corrente (con esso attivato) e usalo pythoncome comando
      • Oppure usa un percorso assoluto con python.exenella cartella dell'ambiente virtuale
    • Per la nuova voce della cartella venv nel comando:
      • Aggiungere un percorso assoluto o relativo alla posizione della cartella finale desiderata.
      • Utilizzare python -m venv my_new_venvper creare un nuovo ambiente virtuale nella directory di lavoro corrente in una nuova my_new_venvcartella.
      • Il nome della cartella venv sarà il nome del venv (quello che appare nel prompt quando viene attivato).
  2. Installa le tue dipendenze dal requirements.txtfile.

    • python -m pip install -r requirements.txt

Potrebbe essere necessario reinstallare i pacchetti locali in modalità di sviluppo.

Nota, se hai bisogno di vedere la posizione specifica in cui è installato un pacchetto, usa:

  • python -m pip list -v
  • L' -vopzione o "verbose" aggiungerà alcune informazioni extra su ogni pacchetto installato, incluso il percorso in cui è installato. Questo è utile per assicurarsi di mantenere i pacchetti virtuali, installati dall'utente e dal sistema.

A questo punto puoi semplicemente eliminare la vecchia cartella venv e tutti i contenuti. Consiglio di utilizzare una GUI per questo: le eliminazioni di file sono spesso permanenti dalla riga di comando di Linux e un piccolo errore di battitura può essere una cattiva notizia.


Non c'è modo di copiare lo stato pip di venv, cioè senza dover scaricare nuovamente tutte le librerie con pip?
Aydo

Non sono sicuro del motivo per cui lo vorresti: è dovuto a una situazione di larghezza di banda estremamente bassa per Internet o alla massiccia necessità di duplicare molto? Credo che potresti ottenere tutte le zip da pypi e quindi installarle localmente, ma non sono al passo con questo. So che puoi configurare un server pip locale per ospitare i pacchetti.
LightCC

Il problema (che sto cercando di risolvere) è che voglio eseguire uno script python su una macchina che non consente al traffico di rete di pip (o, quasi ovunque). Posso metterci dei file, ma non può parlare con pip. Un caso di nicchia di sicuro, ma esattamente perché ho bisogno di spostare queste cose.
Richard Rast

@RichardRast Questo è un problema diverso, sto solo rispondendo alla domanda originale. Nota: ci sono soluzioni al tuo problema (scarica i pacchetti come zip e installa localmente, esegui un server mirror PyPi dietro il tuo firewall, ecc.), Ma questo non è il diritto: Q&A per questo ..
LightCC

2
Puoi creare ruote da tutti i tuoi pacchetti con pip wheel . -w wheelse quindi reinstallare i pacchetti nel nuovo ambiente virtuale conpip install --no-index --find-links /path/to/wheels/ -r requirements.txt
np8

7

L' --relocatableargomento a virtualenvsembra permetterti di farlo.


//, Questo si basa solo su percorsi relativi, o in qualche modo si aggira altrimenti?
Nathan Basanese,

1
--relocatable funziona solo in ambienti virtuali esistenti. Esegui virtualenv --relocatable my-python-venvDOPO che l'ambiente esiste già.
Supplemento

1
Da --help: This fixes up scripts and makes all .pth files relative. No, non creerà librerie indipendenti dalla piattaforma. Se vuoi spostarlo su una piattaforma diversa, devi reinstallarlo in base al python locale.
hilcharge

5
il modulo venv python3 non supporta questo flag
Nelson

7

MA AHIMÈ:

No, non puoi semplicemente mv. Ci sono soluzioni alternative, ma potrebbe essere più facile reinstallare.

(my-python-venv)$ /home/me/PeskyPartyPEnvs/pip3 install foaas
zsh: /home/me/PeskyPartyPEnvs/pip3: bad interpreter: /home/me/Env/my-python-venv/bin/python3: no such file or directory
(my-python-venv)$ deactivate
$ 

... preme entermolto per la frustrazione e il seguente funziona

$
$
$ pip3 search foaas

Tranne che non è da my-python-venv, ergo tristezza.

Vuoi il mvtuo virtualenve usarlo, altrimenti non modificato?

Risposta breve:

Lascerò che Boromir lo dica, così può chiarire:

Beh, non puoi .


2
a meno che tu non voglia diventare cruento e modificarlo in modo appropriato: sono i collegamenti nei binari nel cestino che causano il problema di movimento. Se sai da dove vieni, puoi usare qualcosa come find bin -type f -exec ex -sc "%s,${FROM},${PWD},g|x" {} \;supponendo che il tuo bin e lib siano nella tua cartella venv corrente. Lo uso come un modo rapido e sporco per copiare e spostare gli env virtuali python3 con molti pacchetti pip installati.
Paul Whipp

1
@PaulWhipp C'è qualche vantaggio nell'usare quel comando rispetto al solo utilizzo --relocatable? Inoltre, Nathan, ottima domanda ma questa è una risposta terribile. Accettare la tua risposta è sempre un po 'di parte, a meno che non sia ben scritta e enumeri chiaramente le opzioni, ma determinare che tu stesso sarebbe comunque soggettivo.
Davos

1
@Davos --relocatable non ha funzionato per me, ma sposto regolarmente venv python3 hackerando i binari e finora non ho avuto problemi.
Paul Whipp

1
Stavo suggerendo che dovresti cambiare accettata con una risposta diversa (cioè non tua) Forse quella scelta dalla gente: D
Davos

3
La domanda era "posso semplicemente mvun venv?", E la risposta è "no, non puoi semplicemente mv, ci sono soluzioni alternative ma potrebbe essere più facile reinstallare". Se questa fosse la risposta migliore, farebbe risparmiare tempo a me e ad altri.
Nickolay

5

Sì, questo dovrebbe essere possibile se non hai fatto nulla che dipenda dalla directory corrente di virtualenv.

Tuttavia, se puoi scegliere, la cosa migliore da fare è creare un nuovo virtualenv e iniziare a utilizzare invece il nuovo virtualenv. Questa è la scelta più sicura e meno probabile che causi problemi in seguito.

La documentazione menziona che :

Ogni virtualenv ha informazioni sul percorso hard-coded in esso,

Ad esempio, se hai eseguito setvirtualenvproject, non sarà in grado di passare alla directory corretta dopo l'esecuzione, workon ...quindi in tal caso dovresti risolverlo manualmente.

In generale un virtualenv è poco più di una directory con i file dell'interprete Python necessari più i pacchetti di cui hai bisogno.


3

Usando le risposte di questo e di altri thread su argomenti simili, ho creato uno script bash che, individuato ed eseguito all'interno della directory virtualenv stessa , aiuterà con le tue mosse virtualenv.

Dopo averlo fatto virtualenv --relocatable yourenvdovrai cambiare la tua VIRTUAL_ENVvariabile ogni volta che sposti la directory, quindi se non vuoi cambiarla manualmente, usa questo.

#!/bin/bash \n 
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
EXISTING=$(grep 'VIRTUAL_ENV=' bin/activate)  
NEWDIR=VIRTUAL_ENV=\"$DIR\"
sed -i -e "s|$EXISTING|$NEWDIR|" bin/activate
source bin/activate

Spero possa essere d'aiuto.


1

SI, PUOI! (In windows)

La soluzione alternativa è semplice, sposta il tuo ambiente virtuale ovunque e modifica activate.batall'interno scripts\:

  1. Passa all'ambiente virtuale nella directory desiderata

  2. Fare clic con il pulsante destro del mouse e modificare activate.batsituato in venv_folder\scripts.

  3. Cambia VIRTUAL_ENVvariabile da:

     set VIRTUAL_ENV=C:\old_directory\venv_name
    

    in

     set VIRTUAL_ENV=C:\new_directory\venv_name
    
  4. Salva il file batch modificato e il gioco è fatto!

NOTA: la mia soluzione dovrebbe funzionare e salvare windows users configurazione di nuovi ambienti virtuali, dubito che funzionerà in altri sistemi operativi poiché .batproviene daMS-DOS


1
Cambia old_directoryin old_directory- è un errore di battitura?
ack
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.