Dove va a finire il codice personalizzato in un virtualenv?


107

Che tipo di struttura di directory si dovrebbe seguire quando si usa virtualenv? Ad esempio, se stessi costruendo un'applicazione WSGI e creato un virtualenv chiamato foobar, inizierei con una struttura di directory come:

/foobar
  /bin
    {activate, activate.py, easy_install, python}
  /include
    {python2.6/...}
  /lib
    {python2.6/...}

Una volta creato questo ambiente, dove collocare il proprio:

  • file python?
  • file statici (immagini / ecc.)?
  • confezioni "personalizzate", come quelle disponibili online ma non trovate nel negozio di formaggi?

in relazione alle virtualenvdirectory?

(Supponiamo che io sappia già dove dovrebbero andare le directory virtualenv stesse .)


8
@jkp: non sono d'accordo. Il modo in cui impagini un'applicazione python è una questione diversa da come individui quell'applicazione all'interno di un virtualenv per scopi di sviluppo. È correlato, ma non è lo stesso. Si prega di non chiudere come duplicato.
jcdyer

Risposte:


90

virtualenvfornisce un'istanza dell'interprete Python, non un'istanza dell'applicazione. Normalmente non creeresti i file dell'applicazione all'interno delle directory contenenti il ​​Python predefinito di un sistema, allo stesso modo non è necessario individuare l'applicazione all'interno di una directory virtualenv.

Ad esempio, potresti avere un progetto in cui hai più applicazioni che utilizzano lo stesso virtualenv. Oppure potresti testare un'applicazione con un virtualenv che verrà successivamente distribuito con un sistema Python. Oppure, potresti impacchettare un'app standalone in cui potrebbe avere senso avere la directory virtualenv situata da qualche parte all'interno della directory dell'app stessa.

Quindi, in generale, non credo che ci sia una risposta giusta alla domanda. E una cosa buona virtualenvè che supporta molti casi d'uso diversi: non è necessario che ci sia un modo giusto.


8
Concordato. Uso virtualenv per tutto ciò che faccio e non inserisco mai file nella directory virtualenv. Virtualenv non deve avere alcun impatto sulla struttura del progetto; attiva semplicemente virtualenv (o usa il suo bin / python) e lavora sui tuoi file ovunque li avresti comunque.
Carl Meyer

Sono anche d'accordo di tutto cuore. L'unica volta che ho mai toccare un qualsiasi file all'interno della mia virtualenv (uso io virtualenvwrapper) è quando voglio modificare l' postactivatee postdeactivateganci.
Thane Brimhall

La domanda sarebbe meglio servita con esempi concreti e pratici di diverse opzioni, compresi i compromessi come si vede in altre risposte in questa domanda.
andyfeller

2
È più pulito mantenere il progetto separato dalla virtualenvdirectory, ma il confronto virtualenvcon il sistema python non è di aiuto, perché lo scopo virtualenvè quello di correggere le dipendenze interrotte e isolare i progetti in modo che possano utilizzare diverse versioni del pacchetto e persino versioni di python (mi rendo conto che è stato scritto prima -python3). Consentire alle app di condividere un virtualenvè virtualenvcome se fosse il sistema Python, lasciando le app vulnerabili agli stessi problemi che virtualenv è progettato per risolvere. There should be one obvious way to do it; logicamente dovrebbe essere 1: 1
Davos

@Ned: Sto cercando di acquisire alcune best practice, ma non è ancora chiaro: se hai dozzine di progetti, ognuno con il proprio virtualenv, come fai a tenere traccia di quale progetto viene utilizzato con quale virtualenv? Aggiungi piccoli script di shell nella radice di ogni cartella con il nome del virtualenv con cui lo usi?
ccpizza

57

Se hai solo pochi progetti ogni tanto, nulla ti impedisce di creare un nuovo virtualenv per ognuno e di inserire i tuoi pacchetti direttamente all'interno:

/foobar
  /bin
    {activate, activate.py, easy_install, python}
  /include
    {python2.6/...}
  /lib
    {python2.6/...}
  /mypackage1
    __init__.py
  /mypackage2
    __init__.py

Il vantaggio di questo approccio è che puoi sempre essere sicuro di trovare lo script di attivazione che appartiene al progetto all'interno.

$ cd /foobar
$ source bin/activate
$ python 
>>> import mypackage1
>>>

Se decidi di essere un po 'più organizzato, dovresti considerare di mettere tutti i tuoi virtualenv in una cartella e nominare ciascuno di essi dopo il progetto su cui stai lavorando.

  /virtualenvs
    /foobar
      /bin
        {activate, activate.py, easy_install, python}
      /include
        {python2.6/...}
      /lib
        {python2.6/...}
  /foobar
    /mypackage1
      __init__.py
    /mypackage2
      __init__.py

In questo modo puoi sempre ricominciare da capo con un nuovo virtualenv quando le cose vanno male ei tuoi file di progetto rimangono al sicuro.

Un altro vantaggio è che molti dei tuoi progetti possono utilizzare lo stesso virtualenv, quindi non devi ripetere la stessa installazione più e più volte se hai molte dipendenze.

$ cd /foobar
$ source ../virtualenvs/foobar/bin/activate
$ python 
>>> import mypackage2
>>>

Per gli utenti che devono regolarmente configurare e smontare virtualenvs avrebbe senso guardare virtualenvwrapper.

http://pypi.python.org/pypi/virtualenvwrapper

Con virtualenvwrapper puoi

* create and delete virtual environments

* organize virtual environments in a central place

* easily switch between environments

Non devi più preoccuparti di dove sono i tuoi virtualenv quando lavori sui progetti "foo" e "bar":

  /foo
    /mypackage1
      __init__.py
  /bar
    /mypackage2
      __init__.py

Ecco come inizi a lavorare sul progetto "foo":

$ cd foo
$ workon
bar
foo
$ workon foo
(foo)$ python
>>> import mypackage1
>>>

Quindi passare alla "barra" del progetto è semplice come questo:

$ cd ../bar
$ workon bar
(bar)$ python
>>> import mypackage2
>>>

Abbastanza pulito, non è vero?


Sono assolutamente d'accordo con questa risposta sull'utilizzo virtualenvwrapper. Estrae ordinatamente il virtualenv pur continuando a offrirti tutti i vantaggi.
Thane Brimhall

5
Ma non sono assolutamente d' accordo sul fatto di inserire MAI il tuo codice nell'ambiente virtuale. Se lo vuoi "vicino" al progetto sul filesystem, metti una venv/directory allo stesso livello di quella del progetto BASE_DIR.
Rob Grant

30

Poiché i virtualenv non sono riposizionabili, a mio parere è una cattiva pratica posizionare i file di progetto all'interno di una directory virtualenv. Il virtualenv stesso è un artefatto di sviluppo / distribuzione generato (una specie di file .pyc), non fa parte del progetto; dovrebbe essere facile spazzarlo via e ricrearlo in qualsiasi momento o crearne uno nuovo su un nuovo host di distribuzione, ecc.

Molte persone infatti usano virtualenvwrapper , che rimuove quasi completamente i virtualenv effettivi dalla tua consapevolezza, mettendoli tutti fianco a fianco in $ HOME / .virtualenvs per impostazione predefinita.


Completamente d'accordo sul fatto che sia una cattiva pratica, ottimo sottolineare che dovrebbe essere facile da spazzare via e ricreare, specialmente per testare le distribuzioni e ridurre i pacchetti di requisiti non necessari. Voglio solo aggiungere che virtualenv è possibile riposizionare usando, ad esempio, virtualenv --relocatable myvenvvedere stackoverflow.com/a/6628642/1335793 solo perché puoi non significa che dovresti comunque.
Davos

2

Se dai al tuo progetto una setup.py, pip può importarlo direttamente dal controllo della versione.

Fai qualcosa del genere:

$ virtualenv --no-site-packages myproject
$ . myproject/bin/activate
$ easy_install pip
$ pip install -e hg+http://bitbucket.org/owner/myproject#egg=proj

Il -emetterà il progetto in myproject/src, ma collegarlo a myproject/lib/pythonX.X/site-packages/, quindi tutte le modifiche apportate andranno prelevati subito in moduli che importano dal vostro locale site-packages. Il #eggbit dice a pip quale nome vuoi dare al pacchetto di uova che crea per te.

Se non lo usi --no-site-packages, fai attenzione a specificare che vuoi che pip venga installato in virtualenv con l' -Eopzione

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.