Mã tùy chỉnh đi đâu trong virtualenv?


107

Loại cấu trúc thư mục nào nên tuân theo khi sử dụng virtualenv? Ví dụ: nếu tôi đang xây dựng một ứng dụng WSGI và tạo một virtualenv có tên là foobartôi sẽ bắt đầu với cấu trúc thư mục như:

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

Sau khi môi trường này được tạo, người ta sẽ đặt ở đâu:

  • tệp python?
  • tệp tĩnh (hình ảnh / v.v.)?
  • gói "tùy chỉnh", chẳng hạn như gói có sẵn trực tuyến nhưng không được tìm thấy trong cửa hàng phô mai?

liên quan đến các virtualenvthư mục?

(Giả sử tôi đã biết bản thân các thư mục virtualenv sẽ đi đâu .)


8
@jkp: Tôi không đồng ý. Cách bạn bố trí ứng dụng python là một vấn đề khác với cách bạn định vị ứng dụng đó trong virtualenv cho mục đích phát triển. Nó có liên quan, nhưng không giống nhau. Vui lòng không đóng lại vì trùng lặp.
jcdyer

Câu trả lời:


90

virtualenvcung cấp một phiên bản thông dịch python, không phải một phiên bản ứng dụng. Thông thường, bạn sẽ không tạo các tệp ứng dụng của mình trong các thư mục chứa Python mặc định của hệ thống, tương tự như vậy, không có yêu cầu xác định vị trí ứng dụng của bạn trong một thư mục virtualenv.

Ví dụ: bạn có thể có một dự án mà bạn có nhiều ứng dụng sử dụng cùng một virtualenv. Hoặc, bạn có thể đang thử nghiệm một ứng dụng với virtualenv mà sau này sẽ được triển khai với Python hệ thống. Hoặc, bạn có thể đang đóng gói một ứng dụng độc lập, nơi bạn có thể đặt thư mục virtualenv ở đâu đó trong chính thư mục ứng dụng.

Vì vậy, nói chung, tôi không nghĩ rằng có một câu trả lời đúng cho câu hỏi. Và, một điều tốt virtualenvlà nó hỗ trợ nhiều trường hợp sử dụng khác nhau: không cần phải có một cách đúng.


8
Đã đồng ý. Tôi sử dụng virtualenv cho mọi thứ tôi làm và tôi không bao giờ đặt tệp bên trong thư mục virtualenv. Virtualenv cần không ảnh hưởng đến cấu trúc dự án của bạn; chỉ cần kích hoạt virtualenv (hoặc sử dụng bin / python của nó) và làm việc trên các tệp của bạn ở bất kỳ nơi nào bạn có.
Carl Meyer

Tôi cũng hết lòng đồng ý. Lần duy nhất mà tôi từng chạm vào bất kỳ tập tin bên trong virtualenv của tôi (tôi sử dụng virtualenvwrapper) là khi tôi muốn chỉnh sửa các postactivatepostdeactivatemóc.
Thane Brimhall

Câu hỏi sẽ được giải đáp tốt hơn với các ví dụ cụ thể, thực tế về các lựa chọn khác nhau bao gồm cả sự đánh đổi như đã thấy trong các câu trả lời khác của câu hỏi này.
andyfeller

2
Sẽ sạch hơn nếu giữ dự án của bạn tách biệt với virtualenvthư mục, nhưng so sánh virtualenvvới python hệ thống là vô ích, bởi vì mục đích virtualenvlà sửa các phần phụ thuộc bị hỏng và cô lập các dự án để họ có thể sử dụng các phiên bản gói khác nhau và thậm chí cả phiên bản python (tôi nhận thấy điều này đã được viết trước -python3). Việc cho phép các ứng dụng chia sẻ a virtualenvđang sử dụng virtualenvnhư thể đó là hệ thống python, khiến các ứng dụng dễ bị ảnh hưởng bởi các vấn đề tương tự virtualenv được thiết kế để giải quyết. There should be one obvious way to do it; về mặt logic đó phải là 1: 1
Davos

@Ned: Cố gắng tiếp thu một số phương pháp hay nhất, nhưng vẫn chưa rõ ràng: nếu bạn có hàng tá dự án, mỗi dự án có virtualenv riêng thì làm cách nào để bạn theo dõi dự án nào được sử dụng với virtualenv nào? Thêm các tập lệnh shell nhỏ trong thư mục gốc của mỗi thư mục với tên của virtualenv mà bạn sử dụng cùng?
ccpizza, 18/07/18

57

Nếu bạn chỉ có một vài dự án thường xuyên, không có gì ngăn bạn tạo một virtualenv mới cho mỗi dự án và đặt các gói của bạn ngay bên trong:

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

Ưu điểm của phương pháp này là bạn luôn có thể chắc chắn tìm thấy tập lệnh kích hoạt thuộc về dự án bên trong.

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

Nếu bạn quyết định có tổ chức hơn một chút, bạn nên cân nhắc việc đặt tất cả các virtualenv của mình vào một thư mục và đặt tên cho từng cái theo tên dự án bạn đang thực hiện.

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

Bằng cách này, bạn luôn có thể bắt đầu lại với virtualenv mới khi có sự cố và các tệp dự án của bạn vẫn an toàn.

Một lợi thế khác là một số dự án của bạn có thể sử dụng cùng một virtualenv, vì vậy bạn không cần phải thực hiện cài đặt lặp đi lặp lại cùng một lần nếu bạn có nhiều phụ thuộc.

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

Đối với những người dùng thường xuyên phải thiết lập và gỡ bỏ các virtualenv, sẽ rất hợp lý khi nhìn vào virtualenvwrapper.

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

Với virtualenvwrapper, bạn có thể

* create and delete virtual environments

* organize virtual environments in a central place

* easily switch between environments

Bạn không còn phải lo lắng về vị trí các virtualenv của mình khi làm việc trên các dự án "foo" và "bar":

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

Đây là cách bạn bắt đầu làm việc với dự án "foo":

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

Sau đó, chuyển sang "thanh" của dự án đơn giản như sau:

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

Khá gọn gàng phải không?


Tôi rất đồng ý với câu trả lời này về việc sử dụng virtualenvwrapper. Nó tóm tắt virtualenv một cách gọn gàng trong khi vẫn mang lại cho bạn tất cả các lợi ích.
Thane Brimhall

5
Nhưng hoàn toàn không đồng ý về việc BAO GIỜ đưa mã của bạn vào môi trường ảo. Nếu bạn muốn nó "gần" dự án trên hệ thống tệp thì hãy đặt một venv/thư mục ở cùng cấp với dự án BASE_DIR.
Rob Grant

30

Bởi vì virtualenv không thể di dời, theo ý kiến ​​của tôi, việc đặt các tệp dự án của bạn bên trong thư mục virtualenv là một cách làm không tốt. Bản thân virtualenv là một tạo tác phát triển / triển khai được tạo (giống như tệp .pyc), không phải là một phần của dự án; sẽ dễ dàng loại bỏ nó và tạo lại nó bất cứ lúc nào hoặc tạo một cái mới trên một máy chủ triển khai mới, v.v.

Trên thực tế, nhiều người sử dụng virtualenvwrapper , công cụ này sẽ loại bỏ gần như hoàn toàn các virtualenv thực tế khỏi nhận thức của bạn, đặt tất cả chúng cạnh nhau trong $ HOME / .virtualenvs theo mặc định.


Hoàn toàn đồng ý rằng đó là một thực tiễn xấu, tuyệt vời khi chỉ ra rằng nó sẽ dễ dàng loại bỏ và tạo lại, đặc biệt là đối với triển khai thử nghiệm và loại bỏ các gói yêu cầu không cần thiết. Chỉ muốn thêm virtualenv đó là có thể di chuyển lại bằng cách sử dụng ví dụ: virtualenv --relocatable myvenvxem stackoverflow.com/a/6628642/1335793 chỉ vì bạn có thể không có nghĩa là bạn nên làm như vậy.
Davos

2

Nếu bạn cung cấp cho dự án của mình a setup.py, pip có thể nhập trực tiếp từ kiểm soát phiên bản.

Làm điều gì đó như sau:

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

Ý -echí sẽ đưa dự án vào myproject/src, nhưng liên kết với nó myproject/lib/pythonX.X/site-packages/, vì vậy bất kỳ thay đổi nào bạn thực hiện sẽ được chọn ngay lập tức trong các mô-đun nhập nó từ cục bộ của bạn site-packages. Các #eggchút nói pip gì tên bạn muốn cung cấp cho gói trứng nó tạo ra cho bạn.

Nếu bạn không sử dụng --no-site-packages, hãy cẩn thận chỉ định rằng bạn muốn cài đặt pip vào virtualenv với -Etùy chọn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.