Tôi có thể di chuyển virtualenv không?


89

Câu hỏi này không phải là một bản sao.

Nó không chỉ liên quan đến việc đổi tên một môi trường ảo, mà còn thực sự chuyển nó sang một thư mục khác, bao gồm, có khả năng là thư mục của một người dùng khác.

Điều này không giống như chỉ đổi tên một môi trường ảo, đặc biệt là đối với những người không quen thuộc với virtualenvs.

Nếu tôi tạo một virtualenv và tôi chuyển nó sang một thư mục khác, nó vẫn hoạt động chứ?

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

... sau ngày hôm đó, môi trường ảo ĐÃ CHUYỂN ĐỘNG ...

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

Câu hỏi:

Điều này sẽ hoạt động?

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

Ý tôi là đây không phải là câu hỏi về sự khôn ngoan của việc thử điều này (tất nhiên là trừ khi sự khôn ngoan đó là hài hước), và nhiều hơn nữa về việc liệu nó có khả thi hay không. Tôi thực sự muốn biết liệu nó có thể làm được trong Python 3 hay không, hay liệu tôi chỉ cần thu hút nó và sao chép nó.

Tôi có thể chỉ mvmột virtualenvnhư thế mà không buồn? Tôi muốn tránh nỗi buồn.

Câu trả lời:


69

Đúng. Có thể di chuyển nó trên cùng một nền tảng. Bạn có thể sử dụng --relocatabletrên môi trường hiện có.

Từ --help:

--relocatable - Làm cho một môi trường virtualenv HIỆN TẠI có thể di dời được. Điều này sửa chữa các tập lệnh và làm cho tất cả các tệp .pth trở nên tương đối.

TUY NHIÊN, điều này dường như KHÔNG thay đổi activatetập lệnh, và đúng hơn chỉ thay đổi tập lệnh pip*easy_install*. Trong activatetập lệnh, $VIRTUAL_ENVbiến môi trường được mã hóa cứng là bản gốc /path/to/original/venv. Các $VIRTUAL_ENVbiến được sử dụng để thiết lập các PATHmôi trường hoạt động của bạn quá, vì vậy nó phải được thay đổi dựa trên vị trí mới để gọi pythonpipvv mà không đường dẫn tuyệt đối.

Để khắc phục sự cố này, bạn có thể thay đổi $VIRTUAL_ENVbiến môi trường trong activatetập lệnh (ví dụ: sử dụng sed) và mọi thứ sẽ tốt.

Một ví dụ về cách sử dụng:

$ 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

Hoan hô, bây giờ bạn có thể cài đặt mọi thứ và tải chúng vào môi trường ảo mới được đặt của bạn.


//, Hừm. Điều này dường như không thực sự kết thúc việc làm cho những thứ này có thể di dời được. Tôi tiếp tục gặp một số lỗi về việc chúng không phải là tệp tập lệnh "bình thường".
Nathan Basanese

7
"Tùy chọn --relocatable hiện có một số vấn đề và không được đảm bảo hoạt động trong mọi trường hợp. Có thể tùy chọn này sẽ không được chấp nhận trong phiên bản virtualenv trong tương lai. " (Tôi nhấn mạnh) xem hướng dẫn sử dụng
BobTuckerman

1
Tôi đã thử điều này trên windows và lỗi liệt kê tất cả các tập lệnh (* .py, * .bat, * .ps1) trong Scriptsdir (tương đương với bintrên * nix) và nói điều gì đó giống như activate.ps1 cannot be made relative (it's not a normal script that starts with #!c:\..python.exe.về cơ bản là nó đang phàn nàn rằng hash-bang trong tệp header không phải là python.exe của virtualenv hiện tại, nó là cái mà tôi đã chuyển nó từ -easy fixed. Tôi đã xem trong tập lệnh sang trọng đó và dù sao thì nó cũng đã phát hiện ra con đường riêng của nó - thật tuyệt. Một số tập lệnh khác cũng không dựa vào đường dẫn (ví dụ: deactivate.bat) nên nói ngắn gọn, điều này hoạt động.
Davos

2
@NathanBasanese activate.ps1 cannot be made relativecó thể bỏ qua thông báo vì tập lệnh đó đã là tương đối. Thông báo này không hữu ích trong Windows, bởi vì các tập lệnh không sử dụng các #!chỉ thị như trong Linux để cho shell biết ứng dụng nào sẽ thực thi nó. Nó activate.batkhông được sửa đổi, nhưng nó không được sử dụng (ít nhất là trên windows 10, việc gọi activatekhởi chạy tập lệnh PoSH) nên không, tôi không cần chỉnh sửa bất kỳ tập lệnh nào. Vấn đề là pip.exenó có một đường dẫn đến python được mã hóa cứng và cần chỉnh sửa bằng trình soạn thảo hex hoặc chỉ cần cài đặt lại.
Davos

3
@Sgedda Khi nhìn lại, tôi sẽ nói rằng đừng làm điều này. Môi trường python của bạn phải dễ dàng tạo lại có thể sử dụng ở mức tối thiểu pip freezeđến tệp yêu cầu để bạn có thể dễ dàng cài đặt lại tất cả các gói, docker (hoạt động tốt với virtualenv được cài đặt trên đó), conda, pyenv hoặc một số công cụ khác. Bạn có thể tạo và phá hủy các môi trường như một cơ sở hạ tầng bất biến, chúng không nên quý giá.
Davos

16

Đối với Python 3.3+ (với venvmô-đun tích hợp mới)

Câu trả lời ngắn (bất kể phiên bản):

  • Không có cách nào sạch sẽ, trực tiếp để di chuyển một môi trường ảo
  • Chỉ cần tạo lại, thật dễ dàng !!


Câu trả lời dài:

Kể từ Python v3.3, virtualenvđã trở thành một mô-đun tích hợp có tên venv.

Các --relocatabletùy chọn được đề cập trong câu trả lời khác đã không được đưa vào venv, và hiện không có tốt, cách an toàn mà tôi biết của một trong hai đổi tên hoặc di dời một môi trường ảo Python.

Tuy nhiên, có một cách khá đơn giản để tạo lại một môi trường ảo với tất cả các gói được cài đặt hiện tại của nó. Xem câu trả lời này hoặc xem phần bên dưới để biết thông tin về cách tạo lại môi trường ảo. Trong quá trình này, bạn có thể tạo lại môi trường mới ở bất kỳ vị trí nào và với bất kỳ tên nào bạn muốn. Hoặc xem phần bên dưới để biết quy trình.

Trong câu trả lời đó, anh ấy đề cập đến một số gói bên thứ 3 khác có thể hỗ trợ đổi tên hoặc di chuyển trực tiếp. Nếu bạn quyết tâm theo đuổi một cách để di chuyển một môi trường ảo một cách nguyên vẹn, bạn có thể xem xét liệu những cách đó có venvhiệu quả hay không.

Lưu ý: Trong câu trả lời đó, nó tập trung vào virtualenv, hơn là venv. Xem bên dưới để biết cách dịch.



venvso với virtualenvcú pháp lệnh cũ hơn

Lệnh sử dụng venvlà:

python -m venv

thay vì chỉ virtualenv, cài đặt như một lệnh trong gói gốc. Trong đó "python" đề cập đến cách bạn chạy tệp thực thi python của mình, có thể là nhiều thứ, chẳng hạn như:

  1. python
  2. pyhoặc py -3.7hoặc tương tự ( Trình khởi chạy Python dành cho Windows dành cho Python 3.3+ và chỉ Windows tại thời điểm này)
  3. python3 (quy ước cho môi trường linux cài đặt kép python 2 và 3)
  4. Nếu bạn đang gặp sự cố, hãy sử dụng đường dẫn tuyệt đối đến tệp thực thi python mà bạn muốn chạy: ví dụ: c:\program files\python37\python.exe

Nếu bạn không chắc phiên bản nào đang được chạy, bạn luôn có thể python --versiontìm hiểu.



Cách tạo lại môi trường ảo

Tạo / tạo lại môi trường ảo rất dễ dàng và sẽ trở thành bản chất thứ hai sau khi bạn làm việc với chúng một chút. Quá trình này phản ánh những gì bạn sẽ làm để phân phối tập lệnh của mình dưới dạng một gói (với các phần phụ thuộc của nó) trong nửa đầu và sau đó ai đó sẽ làm gì để cài đặt tập lệnh / gói của bạn để phát triển thêm.

Đầu tiên, nhận danh sách cập nhật về những gì có trong môi trường ảo. Khi nó hoạt động, hãy tải phiên bản Python mà nó sử dụng và lưu danh sách các phần phụ thuộc vào một tệp.

  1. Sử dụng python --versionvới môi trường ảo được kích hoạt để xem nó đang sử dụng phiên bản Python nào.

    • Điều này là rõ ràng - bạn có thể muốn cập nhật phiên bản Python vì nhiều lý do - ít nhất là lên phiên bản vá mới nhất
    • Ví dụ: nếu venv hiện tại đang sử dụng Python v3.7.4, nhưng hiện tại v3.7.6 đã hết - hãy sử dụng v3.7.6 để thay thế, chỉ bao gồm các bản sửa lỗi và bảo mật không vi phạm.
  2. Sử dụng python -m pip freeze > requirements.txtđể tạo danh sách các gói phụ thuộc hiện tại và đưa chúng vào requirements.txttệp. Lệnh này chắc chắn hoạt động trong Linux hoặc Git Bash - không chắc chắn 100% về Powershell hoặc Command Line trong Windows.

Bây giờ tạo một môi trường ảo mới và sau đó thêm các phụ thuộc từ môi trường cũ.

  1. Tạo địa điểm mới của bạn.

    • Đảm bảo rằng bạn đang sử dụng đúng phiên bản python mà bạn muốn cài đặt cho venv.
    • Nếu bạn muốn nó giống hệt phiên bản Python:
      • Chạy python trực tiếp từ môi trường ảo hiện tại (với nó đã được kích hoạt) và chỉ cần sử dụng pythonlàm lệnh
      • Hoặc sử dụng một đường dẫn tuyệt đối với python.exetrong thư mục môi trường ảo
    • Đối với mục nhập thư mục venv mới trong lệnh:
      • Thêm một đường dẫn tuyệt đối hoặc tương đối đến vị trí thư mục cuối cùng mong muốn.
      • Sử dụng python -m venv my_new_venvđể tạo môi trường ảo mới trong my_new_venvthư mục làm việc hiện tại trong thư mục mới .
      • Tên của thư mục venv sẽ là tên của venv (những gì sẽ hiển thị trong lời nhắc khi nó được kích hoạt).
  2. Cài đặt phần phụ thuộc của bạn từ requirements.txttệp.

    • python -m pip install -r requirements.txt

Bạn có thể cần cài đặt lại các gói cục bộ đang ở chế độ phát triển.

Lưu ý, nếu bạn cần xem vị trí cụ thể mà gói được cài đặt, hãy sử dụng:

  • python -m pip list -v
  • Các -vhoặc "verbose" tùy chọn sẽ thêm một số thông tin thêm về mỗi gói được cài đặt, bao gồm cả con đường nó được cài đặt. Điều này rất hữu ích để chắc chắn rằng bạn đang giữ ảo, người dùng, và hệ thống các gói cài đặt thẳng.

Tại thời điểm này, bạn chỉ cần xóa thư mục venv cũ và tất cả nội dung. Tôi khuyên bạn nên sử dụng GUI cho điều đó - việc xóa tệp thường là vĩnh viễn khỏi dòng lệnh linux và một lỗi đánh máy nhỏ có thể là tin xấu.


Không có cách nào sao chép trạng thái pip venv, tức là mà không phải tải lại tất cả các thư viện bằng pip?
Aydo

Tôi không chắc lý do bạn muốn - có phải do tình hình băng thông cực thấp cho Internet hay nhu cầu nhân bản lớn không? Tôi tin rằng bạn có thể lấy tất cả các tệp nén từ pypi và sau đó cài đặt cục bộ, nhưng tôi không bắt kịp điều đó. Tôi biết bạn có thể thiết lập một máy chủ pip cục bộ để lưu trữ các gói.
LightCC

Vấn đề (mà tôi đang cố gắng giải quyết) là tôi muốn chạy một tập lệnh python trên một máy không cho phép lưu lượng mạng chuyển sang pip (hoặc hầu như ở bất kỳ đâu). Tôi có thể đặt các tệp trên đó, nhưng nó không thể nói chuyện với pip. Một trường hợp thích hợp chắc chắn nhưng chính xác tại sao tôi cần phải di chuyển những thứ này.
Richard Rast

@RichardRast Đó là một vấn đề khác, tôi chỉ trả lời câu hỏi ban đầu. Lưu ý: có các giải pháp cho vấn đề của bạn (tải xuống các gói dưới dạng zip và cài đặt cục bộ, chạy máy chủ nhân bản PyPi phía sau tường lửa của bạn, v.v.), nhưng điều này không đúng: Hỏi & Đáp cho điều đó ..
LightCC

2
Bạn có thể tạo bánh xe từ tất cả các gói của mình bằng pip wheel . -w wheelsvà sau đó chỉ cần cài đặt lại các gói trong môi trường ảo mới vớipip install --no-index --find-links /path/to/wheels/ -r requirements.txt
np8

7

Đối --relocatablesố virtualenvxuất hiện để cho phép bạn làm điều này.


//, Điều này chỉ dựa vào các đường dẫn tương đối, hay nó làm xung quanh bằng cách nào khác?
Nathan Basanese

1
--relocatable chỉ hoạt động trong các môi trường ảo hiện có. Chạy virtualenv --relocatable my-python-venvSAU KHI môi trường đã tồn tại.
phụ phí

1
Từ --help: This fixes up scripts and makes all .pth files relative. Không, nó sẽ không tạo ra các thư viện độc lập với nền tảng. Nếu bạn muốn di chuyển nó sang một nền tảng khác, bạn cần phải cài đặt lại nó dựa trên python cục bộ.
hilcharge

5
mô-đun python3 venv không hỗ trợ cờ này
Nelson

7

NHƯNG ALAS:

Không, bạn không thể đơn giản mv. Có những cách giải quyết, nhưng có thể dễ dàng cài đặt lại hơn.

(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
$ 

... nhấn enterrất nhiều vào sự thất vọng, và những điều sau đây hoạt động

$
$
$ pip3 search foaas

Ngoại trừ nó không phải là từ my-python-venv, ergo buồn.

Muốn mvcủa bạn virtualenvvà sử dụng nó, nếu không thì không được sửa đổi?

Câu trả lời ngắn:

Tôi sẽ để Boromir nói điều đó, để anh ấy có thể nói rõ:

Ồ, không thể .


2
trừ khi bạn muốn lấy máu và sửa đổi nó một cách thích hợp: Chính các liên kết trong các tệp nhị phân trong thùng gây ra sự cố chuyển động. Nếu bạn biết bạn đến từ đâu, bạn có thể sử dụng một cái gì đó như find bin -type f -exec ex -sc "%s,${FROM},${PWD},g|x" {} \;giả sử bin và lib của bạn nằm trong thư mục venv hiện tại của bạn. Tôi sử dụng điều này như một cách nhanh chóng và bẩn thỉu để sao chép và di chuyển các env ảo python3 với rất nhiều gói pip được cài đặt.
Paul Whipp 20/02/18

1
@PaulWhipp Có lợi ích gì khi sử dụng lệnh đó so với chỉ sử dụng --relocatablekhông? Ngoài ra, Nathan, câu hỏi tuyệt vời nhưng đây là một câu trả lời khủng khiếp. Chấp nhận câu trả lời của riêng bạn luôn có một chút thành kiến, trừ khi nó được viết tốt và liệt kê rõ ràng các lựa chọn, nhưng dù sao thì việc xác định rằng bản thân sẽ là chủ quan.
Davos

1
@Davos --relocatable không hoạt động với tôi nhưng tôi thường xuyên di chuyển các venvs python3 bằng cách hack mã nhị phân và cho đến nay tôi không gặp bất kỳ sự cố nào.
Paul Whipp

1
Tôi đang gợi ý rằng bạn nên thay đổi được chấp nhận sang một câu trả lời khác (tức là không phải của bạn) Có lẽ là câu trả lời được mọi người chọn: D
Davos

3
Câu hỏi là "tôi có thể đơn giản là mvmột venv không?", Và câu trả lời là "không, bạn không thể đơn giản mv, có những cách giải quyết nhưng có thể dễ dàng hơn để cài đặt lại". Nếu đây là câu trả lời hàng đầu, nó sẽ giúp tôi và những người khác tiết kiệm được một khoảng thời gian.
Nickolay,

5

Có, điều này sẽ khả thi nếu bạn chưa thực hiện bất cứ điều gì phụ thuộc vào thư mục hiện tại của virtualenv.

Tuy nhiên, nếu bạn có quyền lựa chọn, điều tốt nhất nên làm là tạo virtualenv mới và bắt đầu sử dụng virtualenv mới thay thế. Đây là sự lựa chọn an toàn nhất và ít gây ra sự cố sau này.

Tài liệu đề cập đến điều đó :

Mỗi virtualenv có thông tin đường dẫn được mã hóa cứng vào đó,

Ví dụ: nếu bạn đã chạy setvirtualenvprojectthì nó sẽ không thể chuyển sang đúng thư mục sau khi bạn chạy, workon ...vì vậy trong trường hợp đó bạn cần phải sửa lỗi đó theo cách thủ công.

Nói chung, virtualenv không chỉ là một thư mục chứa các tệp thông dịch Python cần thiết cộng với các gói mà bạn cần.


2

Sử dụng các câu trả lời của chủ đề này và các chủ đề khác về chủ đề tương tự, tôi đã tạo một tập lệnh bash, được đặt và thực thi trong chính thư mục virtualenv , sẽ giúp bạn di chuyển virtualenv.

Sau khi thực hiện, virtualenv --relocatable yourenvbạn sẽ cần thay đổi VIRTUAL_ENVbiến mỗi khi di chuyển thư mục, vì vậy nếu bạn không thể thay đổi nó theo cách thủ công, hãy sử dụng tùy chọn này.

#!/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

Tôi hy vọng nó sẽ giúp.


0

CÓ, BẠN CÓ THỂ! (Trong windows)

Cách giải quyết này rất dễ dàng, chỉ cần di chuyển môi trường ảo của bạn đến bất kỳ đâu rồi chỉnh sửa activate.batbên trong scripts\:

  1. Di chuyển đến môi trường ảo đến thư mục mong muốn

  2. Nhấp chuột phải và chỉnh sửa activate.battại venv_folder\scripts.

  3. Thay đổi VIRTUAL_ENVbiến từ:

     set VIRTUAL_ENV=C:\old_directory\venv_name
    

    thành

     set VIRTUAL_ENV=C:\new_directory\venv_name
    
  4. Lưu tệp hàng loạt đã chỉnh sửa và thế là xong!

LƯU Ý: Giải pháp của tôi sẽ hoạt động và lưu windows usersthiết lập môi trường ảo mới, tôi nghi ngờ điều này sẽ hoạt động trong hệ điều hành khác vì .battừMS-DOS


Đổi old_directorythành old_directory- đó có phải là lỗi đánh máy không?
ack

Ôi, chết tiệt, vâng, cảm ơn bạn
kyle olodin
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.