Gdzie w virtualenv znajduje się kod niestandardowy?

107

Jakiej struktury katalogów należy przestrzegać podczas używania virtualenv? Na przykład, gdybym budował aplikację WSGI i tworzył virtualenv o nazwie foobar, zacząłbym od struktury katalogów takiej jak:

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

Po utworzeniu tego środowiska, gdzie można umieścić własne:

  • pliki python?
  • pliki statyczne (obrazy / itp.)?
  • Opakowania „niestandardowe”, takie jak te dostępne online, których nie można znaleźć w sklepie z serami?

w stosunku do virtualenvkatalogów?

(Załóżmy, że już wiem, gdzie powinny znajdować się same katalogi virtualenv ).

Phillip B Oldham
źródło
8
@jkp: Nie zgadzam się. Sposób rozmieszczenia aplikacji w języku Python różni się od sposobu lokalizowania tej aplikacji w virtualenv do celów programistycznych. To jest powiązane, ale nie to samo. Proszę nie zamykać jako duplikat.
jcdyer

Odpowiedzi:

90

virtualenvudostępnia instancję interpretera języka Python, a nie instancję aplikacji. Zwykle nie tworzyłbyś plików aplikacji w katalogach zawierających domyślny systemowy Python, podobnie nie ma wymagania, aby lokalizować aplikację w katalogu virtualenv.

Na przykład możesz mieć projekt, w którym masz wiele aplikacji korzystających z tego samego virtualenv. Lub możesz testować aplikację za pomocą virtualenv, który zostanie później wdrożony w systemowym Pythonie. Lub możesz pakować samodzielną aplikację, w której sensowne może być umieszczenie katalogu virtualenv gdzieś w samym katalogu aplikacji.

Tak więc, ogólnie rzecz biorąc, nie sądzę, aby istniała jedna prawidłowa odpowiedź na to pytanie. I dobrą rzeczą virtualenvjest to, że obsługuje wiele różnych przypadków użycia: nie musi być jeden właściwy sposób.

Ned Deily
źródło
8
Zgoda. Używam virtualenv do wszystkiego, co robię i nigdy nie umieszczam plików w katalogu virtualenv. Virtualenv nie musi mieć żadnego wpływu na strukturę Twojego projektu; po prostu aktywuj virtualenv (lub użyj jego bin / python) i pracuj na swoich plikach, gdziekolwiek je masz.
Carl Meyer
Całkowicie się z tym zgadzam. Jedyny przypadek, w którym dotykam plików w moim virtualenv (używam virtualenvwrapper), jest wtedy, gdy chcę edytować podpięcia postactivatei postdeactivate.
Thane Brimhall
Pytaniu lepiej byłoby podać konkretne, praktyczne przykłady różnych opcji, w tym kompromisów, jak widać w innych odpowiedziach na to pytanie.
andyfeller
2
Oddzielenie projektu od virtualenvkatalogu jest czystsze , ale porównanie virtualenvdo systemu python jest niepomocne, ponieważ celem virtualenvjest naprawianie zepsutych zależności i izolowanie projektów, aby mogły używać różnych wersji pakietów, a nawet wersji Pythona (zdaję sobie sprawę, że zostało to napisane wcześniej -python3). Zezwalanie aplikacjom na współużytkowanie pliku virtualenvużywa virtualenvtak, jakby to był systemowy Python, pozostawiając aplikacje podatne na te same problemy, które ma rozwiązać virtualenv. There should be one obvious way to do it; logicznie powinno to być 1: 1
Davos
@Ned: Próbujesz zdobyć kilka najlepszych praktyk, ale nadal nie jest jasne: jeśli masz dziesiątki projektów, każdy z własnym virtualenv, to w jaki sposób możesz śledzić, który projekt jest używany z którym virtualenv? Dodać małe skrypty powłoki w katalogu głównym każdego folderu z nazwą virtualenv, z którym go używasz?
ccpizza
57

Jeśli masz tylko kilka projektów co jakiś czas, nic nie stoi na przeszkodzie, aby utworzyć nowy virtualenv dla każdego z nich i umieścić swoje pakiety bezpośrednio w środku:

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

Zaletą tego podejścia jest to, że zawsze możesz być pewien, że w środku znajdziesz skrypt aktywacyjny należący do projektu.

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

Jeśli zdecydujesz się na nieco bardziej zorganizowaną organizację, powinieneś pomyśleć o umieszczeniu wszystkich swoich virtualenvów w jednym folderze i nazwać każdy z nich po projekcie, nad którym pracujesz.

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

W ten sposób zawsze możesz zacząć od nowa z nowym virtualenvem, gdy coś pójdzie nie tak, a pliki projektu pozostaną bezpieczne.

Kolejną zaletą jest to, że kilka projektów może korzystać z tego samego virtualenv, więc nie musisz powtarzać tej samej instalacji, jeśli masz wiele zależności.

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

W przypadku użytkowników, którzy regularnie muszą konfigurować i niszczyć virtualenv, warto przyjrzeć się virtualenvwrapper.

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

Z virtualenvwrapper możesz

* create and delete virtual environments

* organize virtual environments in a central place

* easily switch between environments

Nie musisz już martwić się o to, gdzie są twoje virtualenvy podczas pracy nad projektami „foo” i „bar”:

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

Oto jak zaczynasz pracę nad projektem „foo”:

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

W takim przypadku przejście na „pasek” projektu jest tak proste:

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

Całkiem fajnie, prawda?

Maik Röder
źródło
I zdecydowanie zgadzam się z tym odpowiedź na temat korzystania virtualenvwrapper. Starannie oddziela virtualenv, a jednocześnie zapewnia wszystkie korzyści.
Thane Brimhall
5
Ale zdecydowanie nie zgadzam się z tym, że NIGDY nie umieszczasz swojego kodu w środowisku wirtualnym. Jeśli chcesz, aby był "blisko" projektu w systemie plików, umieść venv/katalog na tym samym poziomie co projekt BASE_DIR.
Rob Grant
30

Ponieważ virtualenv nie można przenosić, moim zdaniem umieszczanie plików projektu w katalogu virtualenv jest złą praktyką. Sam virtualenv jest wygenerowanym artefaktem programowania / wdrażania (coś w rodzaju pliku .pyc), a nie częścią projektu; powinno być łatwe do zdmuchnięcia i odtworzenia w dowolnym momencie lub utworzenie nowego na nowym hoście wdrażania itp.

W rzeczywistości wiele osób korzysta z virtualenvwrapper , który prawie całkowicie usuwa rzeczywiste virtualenv z twojej świadomości, domyślnie umieszczając je wszystkie obok siebie w $ HOME / .virtualenvs.

Carl Meyer
źródło
Całkowicie się zgadzam, że to zła praktyka. Wspaniale jest wskazać, że powinno być łatwo zdmuchnąć i odtworzyć, zwłaszcza w celu testowania wdrożeń i eliminowania niepotrzebnych pakietów wymagań. Chcę tylko dodać, że virtualenv można przenieść za pomocą np. virtualenv --relocatable myvenvStrony stackoverflow.com/a/6628642/1335793 tylko dlatego, że możesz, nie znaczy, że powinieneś.
Davos
2

Jeśli nadasz projektowi a setup.py, pip może zaimportować go bezpośrednio z kontroli wersji.

Zrób coś takiego:

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

Projekt -eumieści projekt myproject/src, ale połączy go z nim myproject/lib/pythonX.X/site-packages/, więc wszelkie wprowadzone zmiany zostaną natychmiast odebrane w modułach, które importują go z lokalnego site-packages. Ten #eggbit mówi pipowi, jaką nazwę chcesz nadać paczce jajek, którą dla ciebie utworzy.

Jeśli nie używasz --no-site-packages, uważaj, aby określić, że chcesz zainstalować pip w virtualenv za pomocą -Eopcji

jcdyer
źródło