venv --- Tạo môi trường ảo

Added in version 3.3.

Source code: Lib/venv/


Mô-đun venv hỗ trợ tạo các "môi trường ảo" nhẹ, mỗi môi trường có bộ gói Python độc lập riêng được cài đặt trong thư mục site. Một môi trường ảo được tạo dựa trên bản cài đặt Python hiện có, được gọi là Python "cơ sở" của môi trường ảo và theo mặc định được tách biệt khỏi các gói trong môi trường cơ sở, do đó chỉ những gói được cài đặt rõ ràng trong môi trường ảo mới khả dụng. Xem virtual environments documentation của Môi trường ảosite để biết thêm thông tin.

Khi được sử dụng từ bên trong môi trường ảo, các công cụ cài đặt phổ biến như pip sẽ cài đặt các gói Python vào môi trường ảo mà không cần phải yêu cầu thực hiện điều đó một cách rõ ràng.

Một môi trường ảo là (trong số những thứ khác):

  • Được sử dụng để chứa trình thông dịch Python cụ thể và các thư viện phần mềm cũng như các tệp nhị phân cần thiết để hỗ trợ một dự án (thư viện hoặc ứng dụng). Theo mặc định, chúng được tách biệt khỏi phần mềm trong các môi trường ảo khác cũng như các trình thông dịch và thư viện Python được cài đặt trong hệ điều hành.

  • Chứa trong một thư mục, thường được đặt tên là .venv hoặc venv trong thư mục dự án hoặc trong thư mục chứa cho nhiều môi trường ảo, chẳng hạn như ~/.virtualenvs.

  • Chưa được kiểm tra trong các hệ thống kiểm soát nguồn như Git.

  • Được coi là dùng một lần -- việc xóa và tạo lại nó từ đầu sẽ rất đơn giản. Bạn không đặt bất kỳ mã dự án nào trong môi trường.

  • Không được coi là có thể di chuyển hoặc có thể sao chép -- bạn chỉ cần tạo lại môi trường tương tự ở vị trí mục tiêu.

Xem PEP 405 để biết thêm thông tin cơ bản về môi trường ảo Python.

sẵn có: not Android, not iOS, not WASI.

Mô-đun này không được hỗ trợ trên mobile platforms hoặc WebAssembly platforms.

Tạo môi trường ảo

Virtual environments được tạo bằng cách thực thi mô-đun venv:

python -m venv /path/to/new/ảo/môi trường

Thao tác này sẽ tạo thư mục đích (bao gồm cả thư mục mẹ nếu cần) và đặt tệp pyvenv.cfg vào đó với khóa home trỏ đến bản cài đặt Python mà lệnh được chạy từ đó. Nó cũng tạo một thư mục con bin (hoặc Scripts trên Windows) chứa bản sao hoặc liên kết tượng trưng của tệp thực thi Python (phù hợp với nền tảng hoặc đối số được sử dụng tại thời điểm tạo môi trường). Nó cũng tạo một thư mục con lib/pythonX.Y/site-packages (trên Windows, đây là Lib\site-packages). Nếu một thư mục hiện có được chỉ định, nó sẽ được sử dụng lại.

Thay đổi trong phiên bản 3.5: Việc sử dụng venv hiện được khuyến nghị để tạo môi trường ảo.

Không được dùng nữa kể từ phiên bản 3.6, đã bị xóa trong phiên bản 3.8: pyvenv là công cụ được đề xuất để tạo môi trường ảo cho Python 3.3 và 3.4 và được thay thế trong 3.5 bằng cách thực thi trực tiếp venv.

Trên Windows, gọi lệnh venv như sau:

PS> python -m venv C:\path\to\new\virtual\environment

Lệnh, nếu chạy với -h, sẽ hiển thị các tùy chọn có sẵn:

cách sử dụng: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]
            [--nâng cấp] [--không có pip] [--prompt PROMPT] [--upgrade-deps]
            [--không có-scm-bỏ qua-tập tin]
            ENV_DIR [ENV_DIR ...]

Tạo môi trường Python ảo trong một hoặc nhiều thư mục đích.

Khi một môi trường đã được tạo, bạn có thể muốn kích hoạt nó, ví dụ: bởi
tìm nguồn tập lệnh kích hoạt trong thư mục bin của nó.
ENV_DIR

Đối số bắt buộc chỉ định thư mục để tạo môi trường.

--system-site-packages

Cấp cho môi trường ảo quyền truy cập vào thư mục gói trang web của hệ thống.

Cố gắng sử dụng liên kết tượng trưng thay vì bản sao, khi liên kết tượng trưng không phải là mặc định cho nền tảng.

--copies

Cố gắng sử dụng các bản sao thay vì liên kết tượng trưng, ​​ngay cả khi liên kết tượng trưng là mặc định cho nền tảng.

--clear

Xóa nội dung của thư mục môi trường nếu nó đã tồn tại trước khi tạo môi trường.

--upgrade

Nâng cấp thư mục môi trường để sử dụng phiên bản Python này, giả sử Python đã được nâng cấp tại chỗ.

--without-pip

Bỏ qua việc cài đặt hoặc nâng cấp pip trong môi trường ảo (pip được khởi động theo mặc định).

--prompt <PROMPT>

Cung cấp tiền tố nhắc thay thế cho môi trường này.

--upgrade-deps

Nâng cấp các phần phụ thuộc cốt lõi (pip) lên phiên bản mới nhất trong PyPI.

--without-scm-ignore-files

Bỏ qua việc thêm SCM bỏ qua các tệp vào thư mục môi trường (Git được hỗ trợ theo mặc định).

Thay đổi trong phiên bản 3.4: Cài đặt pip theo mặc định, thêm tùy chọn --without-pip--copies.

Thay đổi trong phiên bản 3.4: Trong các phiên bản trước, nếu thư mục đích đã tồn tại thì sẽ xảy ra lỗi, trừ khi tùy chọn --clear hoặc --upgrade được cung cấp.

Thay đổi trong phiên bản 3.9: Thêm tùy chọn --upgrade-deps để nâng cấp pip + setuptools lên mới nhất trên PyPI.

Thay đổi trong phiên bản 3.12: setuptools không còn phụ thuộc vào venv cốt lõi nữa.

Thay đổi trong phiên bản 3.13: Đã thêm tùy chọn --without-scm-ignore-files.

Thay đổi trong phiên bản 3.13: venv hiện tạo tệp .gitignore cho Git theo mặc định.

Ghi chú

Mặc dù các liên kết tượng trưng được hỗ trợ trên Windows nhưng chúng không được khuyến khích. Đặc biệt lưu ý là việc nhấp đúp vào python.exe trong File Explorer sẽ giải quyết liên kết tượng trưng một cách nhanh chóng và bỏ qua môi trường ảo.

Ghi chú

Trên Microsoft Windows, có thể cần phải bật tập lệnh Activate.ps1 bằng cách đặt chính sách thực thi cho người dùng. Bạn có thể thực hiện việc này bằng cách ban hành lệnh PowerShell sau:

PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Xem About Execution Policies để biết thêm thông tin.

Tệp pyvenv.cfg đã tạo cũng bao gồm khóa include-system-site-packages, được đặt thành true nếu venv được chạy với tùy chọn --system-site-packages, nếu không thì false.

Trừ khi tùy chọn --without-pip được cung cấp, ensurepip sẽ được gọi để khởi động pip vào môi trường ảo.

Nhiều đường dẫn có thể được cấp cho venv, trong trường hợp đó, một môi trường ảo giống hệt nhau sẽ được tạo, theo các tùy chọn đã cho, tại mỗi đường dẫn được cung cấp.

Venv hoạt động như thế nào

Khi trình thông dịch Python đang chạy từ môi trường ảo, sys.prefixsys.exec_prefix trỏ đến các thư mục của môi trường ảo, trong khi sys.base_prefixsys.base_exec_prefix trỏ đến các thư mục của Python cơ sở được sử dụng để tạo môi trường. Việc kiểm tra sys.prefix != sys.base_prefix là đủ để xác định xem trình thông dịch hiện tại có đang chạy từ môi trường ảo hay không.

Một môi trường ảo có thể được "kích hoạt" bằng cách sử dụng tập lệnh trong thư mục nhị phân của nó (bin trên POSIX; Scripts trên Windows). Thao tác này sẽ thêm thư mục đó vào PATH của bạn, để việc chạy python sẽ gọi trình thông dịch Python của môi trường và bạn có thể chạy các tập lệnh đã cài đặt mà không cần phải sử dụng đường dẫn đầy đủ của chúng. Lệnh gọi tập lệnh kích hoạt dành riêng cho nền tảng (<venv> phải được thay thế bằng đường dẫn đến thư mục chứa môi trường ảo):

Nền tảng

Vỏ

Lệnh kích hoạt môi trường ảo

POSIX

bash/zsh

$ source <venv>/bin/activate

$ source <venv>/bin/activate.fish

csh/tcsh

$ source <venv>/bin/activate.csh

ôi

$ <venv>/bin/Activate.ps1

cửa sổ

cmd.exe

C:\> <venv>\Scripts\activate.bat

PowerShell

PS C:\> <venv>\Scripts\Activate.ps1

Added in version 3.4: tập lệnh kích hoạt fishcsh.

Added in version 3.8: Tập lệnh kích hoạt PowerShell được cài đặt trong POSIX để hỗ trợ PowerShell Core.

Bạn không cần phải need cụ thể để kích hoạt một môi trường ảo, vì bạn chỉ có thể chỉ định đường dẫn đầy đủ đến trình thông dịch Python của môi trường đó khi gọi Python. Hơn nữa, tất cả các tập lệnh được cài đặt trong môi trường đều có thể chạy được mà không cần kích hoạt nó.

Để đạt được điều này, các tập lệnh được cài đặt vào môi trường ảo có dòng "shebang" trỏ đến trình thông dịch Python của môi trường, #!/<path-to-venv>/bin/python. Điều này có nghĩa là tập lệnh sẽ chạy với trình thông dịch đó bất kể giá trị của PATH. Trên Windows, xử lý dòng "shebang" được hỗ trợ nếu bạn đã cài đặt Trình quản lý cài đặt Python. Do đó, việc bấm đúp vào tập lệnh đã cài đặt trong cửa sổ Windows Explorer sẽ chạy tập lệnh đó với trình thông dịch chính xác mà không cần kích hoạt môi trường hoặc trên PATH.

Khi một môi trường ảo đã được kích hoạt, biến môi trường VIRTUAL_ENV được đặt thành đường dẫn của môi trường. Vì không cần phải kích hoạt rõ ràng môi trường ảo để sử dụng nó nên không thể dựa vào VIRTUAL_ENV để xác định xem môi trường ảo có đang được sử dụng hay không.

Cảnh báo

Vì các tập lệnh được cài đặt trong môi trường không nên yêu cầu môi trường được kích hoạt nên các dòng shebang của chúng chứa đường dẫn tuyệt đối đến trình thông dịch của môi trường. Bởi vì điều này, trong trường hợp chung, các môi trường vốn không thể di chuyển được. Bạn phải luôn có một phương tiện đơn giản để tạo lại môi trường (ví dụ: nếu bạn có tệp yêu cầu requirements.txt, bạn có thể gọi pip install -r requirements.txt bằng cách sử dụng pip của môi trường để cài đặt tất cả các gói mà môi trường cần). Nếu vì bất kỳ lý do gì bạn cần di chuyển môi trường đến một vị trí mới, bạn nên tạo lại nó ở vị trí mong muốn và xóa môi trường ở vị trí cũ. Nếu bạn di chuyển một môi trường vì bạn đã di chuyển thư mục mẹ của nó, bạn nên tạo lại môi trường đó ở vị trí mới. Nếu không, phần mềm được cài đặt vào môi trường có thể không hoạt động như mong đợi.

Bạn có thể hủy kích hoạt môi trường ảo bằng cách nhập deactivate vào shell của mình. Cơ chế chính xác dành riêng cho nền tảng và là chi tiết triển khai nội bộ (thông thường, tập lệnh hoặc hàm shell sẽ được sử dụng).

API

Phương pháp cấp cao được mô tả ở trên sử dụng API đơn giản, cung cấp cơ chế cho người tạo môi trường ảo bên thứ ba tùy chỉnh việc tạo môi trường theo nhu cầu của họ, lớp EnvBuilder.

class venv.EnvBuilder(system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False, prompt=None, upgrade_deps=False, *, scm_ignore_files=frozenset())

Lớp EnvBuilder chấp nhận các đối số từ khóa sau khi khởi tạo:

  • system_site_packages -- một giá trị boolean chỉ ra rằng các gói trang web Python của hệ thống phải có sẵn cho môi trường (mặc định là False).

  • clear -- một giá trị boolean, nếu đúng, sẽ xóa nội dung của bất kỳ thư mục đích hiện có nào trước khi tạo môi trường.

  • symlinks -- một giá trị boolean cho biết có nên cố gắng liên kết tượng trưng nhị phân Python thay vì sao chép hay không.

  • upgrade -- một giá trị boolean, nếu đúng, sẽ nâng cấp môi trường hiện có với Python đang chạy - để sử dụng khi Python đó đã được nâng cấp tại chỗ (mặc định là False).

  • with_pip -- một giá trị boolean, nếu đúng, đảm bảo pip được cài đặt trong môi trường ảo. Điều này sử dụng ensurepip với tùy chọn --default-pip.

  • prompt -- một chuỗi được sử dụng sau khi môi trường ảo được kích hoạt (mặc định là None có nghĩa là tên thư mục của môi trường sẽ được sử dụng). Nếu chuỗi đặc biệt "." được cung cấp, tên cơ sở của thư mục hiện tại sẽ được sử dụng làm dấu nhắc.

  • upgrade_deps -- Cập nhật các mô-đun venv cơ sở lên phiên bản mới nhất trên PyPI

  • scm_ignore_files -- Tạo các tệp bỏ qua dựa trên trình quản lý kiểm soát nguồn được chỉ định (SCM) trong iterable. Hỗ trợ được xác định bằng phương thức có tên create_{scm}_ignore_file. Giá trị duy nhất được hỗ trợ theo mặc định là "git" qua create_git_ignore_file().

Thay đổi trong phiên bản 3.4: Đã thêm tham số with_pip

Thay đổi trong phiên bản 3.6: Đã thêm tham số prompt

Thay đổi trong phiên bản 3.9: Đã thêm tham số upgrade_deps

Thay đổi trong phiên bản 3.13: Đã thêm tham số scm_ignore_files

EnvBuilder có thể được sử dụng làm lớp cơ sở.

create(env_dir)

Tạo một môi trường ảo bằng cách chỉ định thư mục đích (tuyệt đối hoặc tương đối với thư mục hiện tại) chứa môi trường ảo. Phương thức create sẽ tạo môi trường trong thư mục được chỉ định hoặc đưa ra một ngoại lệ thích hợp.

Phương thức create của lớp EnvBuilder minh họa các hook có sẵn để tùy chỉnh lớp con:

def tạo (tự, env_dir):
    """
    Tạo môi trường Python ảo hóa trong một thư mục.
    env_dir là thư mục đích để tạo môi trường.
    """
    env_dir = os.path.abspath(env_dir)
    bối cảnh = self.ensure_directories(env_dir)
    self.create_configuration(ngữ cảnh)
    self.setup_python(ngữ cảnh)
    self.setup_scripts(ngữ cảnh)
    self.post_setup(ngữ cảnh)

Mỗi phương thức ensure_directories(), create_configuration(), setup_python(), setup_scripts()post_setup() đều có thể bị ghi đè.

ensure_directories(env_dir)

Tạo thư mục môi trường và tất cả các thư mục con cần thiết chưa tồn tại và trả về một đối tượng ngữ cảnh. Đối tượng bối cảnh này chỉ là nơi chứa các thuộc tính (chẳng hạn như đường dẫn) để các phương thức khác sử dụng. Nếu EnvBuilder được tạo bằng arg clear=True, nội dung của thư mục môi trường sẽ bị xóa và sau đó tất cả các thư mục con cần thiết sẽ được tạo lại.

Đối tượng bối cảnh được trả về là types.SimpleNamespace với các thuộc tính sau:

  • env_dir - Vị trí của môi trường ảo. Được sử dụng cho __VENV_DIR__ trong tập lệnh kích hoạt (xem install_scripts()).

  • env_name - Tên của môi trường ảo. Được sử dụng cho __VENV_NAME__ trong tập lệnh kích hoạt (xem install_scripts()).

  • prompt - Lời nhắc được sử dụng bởi tập lệnh kích hoạt. Được sử dụng cho __VENV_PROMPT__ trong tập lệnh kích hoạt (xem install_scripts()).

  • executable - Tệp thực thi Python cơ bản được môi trường ảo sử dụng. Điều này tính đến trường hợp môi trường ảo được tạo từ một môi trường ảo khác.

  • inc_path - Đường dẫn bao gồm môi trường ảo.

  • lib_path - Đường dẫn purelib cho môi trường ảo.

  • bin_path - Đường dẫn tập lệnh cho môi trường ảo.

  • bin_name - Tên của đường dẫn tập lệnh liên quan đến vị trí môi trường ảo. Được sử dụng cho __VENV_BIN_NAME__ trong tập lệnh kích hoạt (xem install_scripts()).

  • env_exe - Tên của trình thông dịch Python trong môi trường ảo. Được sử dụng cho __VENV_PYTHON__ trong tập lệnh kích hoạt (xem install_scripts()).

  • env_exec_cmd - Tên của trình thông dịch Python, có tính đến các chuyển hướng hệ thống tệp. Điều này có thể được sử dụng để chạy Python trong môi trường ảo.

Thay đổi trong phiên bản 3.11: venv sysconfig installation scheme được sử dụng để xây dựng đường dẫn của các thư mục đã tạo.

Thay đổi trong phiên bản 3.12: Thuộc tính lib_path đã được thêm vào ngữ cảnh và đối tượng ngữ cảnh đã được ghi lại.

create_configuration(context)

Tạo tệp cấu hình pyvenv.cfg trong môi trường.

setup_python(context)

Tạo một bản sao hoặc liên kết tượng trưng đến tệp thực thi Python trong môi trường. Trên các hệ thống POSIX, nếu một python3.x thực thi cụ thể được sử dụng, các liên kết tượng trưng đến pythonpython3 sẽ được tạo trỏ đến tệp thực thi đó, trừ khi các tệp có tên đó đã tồn tại.

setup_scripts(context)

Cài đặt các tập lệnh kích hoạt phù hợp với nền tảng vào môi trường ảo.

upgrade_dependencies(context)

Nâng cấp các gói phụ thuộc venv cốt lõi (hiện tại là pip) trong môi trường. Điều này được thực hiện bằng cách phân tách tệp thực thi pip trong môi trường.

Added in version 3.9.

Thay đổi trong phiên bản 3.12: setuptools không còn phụ thuộc vào venv cốt lõi nữa.

post_setup(context)

Phương pháp giữ chỗ có thể được ghi đè trong quá trình triển khai của bên thứ ba để cài đặt sẵn các gói trong môi trường ảo hoặc thực hiện các bước hậu tạo khác.

install_scripts(context, path)

Phương thức này có thể được gọi từ setup_scripts() hoặc post_setup() trong các lớp con để hỗ trợ cài đặt các tập lệnh tùy chỉnh vào môi trường ảo.

path là đường dẫn đến thư mục chứa các thư mục con common, posix, nt; mỗi tập lệnh chứa các tập lệnh dành cho thư mục bin trong môi trường. Nội dung của common và thư mục tương ứng với os.name được sao chép sau khi thay thế một số văn bản giữ chỗ:

  • __VENV_DIR__ được thay thế bằng đường dẫn tuyệt đối của thư mục môi trường.

  • __VENV_NAME__ được thay thế bằng tên môi trường (đoạn đường dẫn cuối cùng của thư mục môi trường).

  • __VENV_PROMPT__ được thay thế bằng dấu nhắc (tên môi trường được bao quanh bởi dấu ngoặc đơn và có khoảng trắng sau)

  • __VENV_BIN_NAME__ được thay thế bằng tên của thư mục bin (bin hoặc Scripts).

  • __VENV_PYTHON__ được thay thế bằng đường dẫn tuyệt đối của tệp thực thi của môi trường.

Các thư mục được phép tồn tại (khi môi trường hiện tại đang được nâng cấp).

create_git_ignore_file(context)

Tạo tệp .gitignore trong môi trường ảo khiến toàn bộ thư mục bị trình quản lý kiểm soát nguồn Git bỏ qua.

Added in version 3.13.

Thay đổi trong phiên bản 3.7.2: Windows hiện sử dụng tập lệnh chuyển hướng cho python[w].exe thay vì sao chép các tệp nhị phân thực tế. Trong 3.7.2 chỉ setup_python() không làm gì trừ khi chạy từ bản dựng trong cây nguồn.

Thay đổi trong phiên bản 3.7.3: Windows sao chép các tập lệnh chuyển hướng như một phần của setup_python() thay vì setup_scripts(). Đây không phải là trường hợp trong 3.7.2. Khi sử dụng liên kết tượng trưng, ​​các tệp thực thi ban đầu sẽ được liên kết.

Ngoài ra còn có chức năng tiện lợi cấp mô-đun:

venv.create(env_dir, system_site_packages=False, clear=False, symlinks=False, with_pip=False, prompt=None, upgrade_deps=False, *, scm_ignore_files=frozenset())

Tạo một EnvBuilder với các đối số từ khóa đã cho và gọi phương thức create() của nó bằng đối số env_dir.

Added in version 3.3.

Thay đổi trong phiên bản 3.4: Đã thêm tham số with_pip

Thay đổi trong phiên bản 3.6: Đã thêm tham số prompt

Thay đổi trong phiên bản 3.9: Đã thêm tham số upgrade_deps

Thay đổi trong phiên bản 3.13: Đã thêm tham số scm_ignore_files

Một ví dụ về việc mở rộng EnvBuilder

Tập lệnh sau đây cho biết cách mở rộng EnvBuilder bằng cách triển khai một lớp con cài đặt setuptools và pip vào môi trường ảo đã tạo:

hệ điều hành nhập khẩu
nhập os.path
từ nhập quy trình con Popen, PIPE
hệ thống nhập khẩu
từ nhập luồng Chủ đề
từ urllib.parse nhập urlsplit
từ urllib.request nhập urlretrieve
nhập khẩu

lớp ExtendedEnvBuilder(venv.EnvBuilder):
    """
    Trình tạo này cài đặt các công cụ thiết lập và pip để bạn có thể pip hoặc
    easy_install các gói khác vào môi trường ảo đã tạo.

    :param gật đầu: Nếu đúng, setuptools và pip không được cài đặt vào
                   tạo môi trường ảo.
    :param nopip: Nếu đúng, pip chưa được cài đặt vào tệp đã tạo
                  môi trường ảo.
    :param Progress: Nếu setuptools hoặc pip được cài đặt, tiến trình của
                     quá trình cài đặt có thể được theo dõi bằng cách chuyển một tiến trình
                     có thể gọi được. Nếu được chỉ định, nó được gọi với hai
                     đối số: một chuỗi biểu thị một số tiến trình và một
                     ngữ cảnh cho biết chuỗi đến từ đâu.
                     Đối số bối cảnh có thể có một trong ba giá trị:
                     'chính', chỉ ra rằng nó được gọi từ virtualize()
                     chính nó, và 'stdout' và 'stderr', thu được
                     bằng cách đọc các dòng từ luồng đầu ra của một quy trình con
                     được sử dụng để cài đặt ứng dụng.

                     Nếu một cuộc gọi có thể không được chỉ định, tiến trình mặc định
                     thông tin được xuất ra sys.stderr.
    """

    def __init__(self, *args, **kwargs):
        self.nodist = kwargs.pop('nodist', Sai)
        self.nopip = kwargs.pop('nopip', Sai)
        self.progress = kwargs.pop('progress', None)
        self.verbose = kwargs.pop('dài dòng', Sai)
        super().__init__(*args, **kwargs)

    def post_setup(tự, ngữ cảnh):
        """
        Thiết lập bất kỳ gói nào cần được cài đặt sẵn vào
        môi trường ảo đang được tạo.

        :param context: Thông tin về môi trường ảo
                        yêu cầu tạo đang được xử lý.
        """
        os.environ['VIRTUAL_ENV'] = context.env_dir
        nếu không phải  self.nodist:
            self.install_setuptools(ngữ cảnh)
        # Can không cài đặt pip nếu không có setuptools
        nếu không phải self.nopip  không phải self.nodist:
            self.install_pip(ngữ cảnh)

    trình đọc def (tự, luồng, ngữ cảnh):
        """
        Đọc các dòng từ luồng đầu ra của quy trình con và chuyển sang tiến trình
        có thể gọi được (nếu được chỉ định) hoặc ghi thông tin tiến trình vào sys.stderr.
        """
        tiến độ = self.progress
        trong khi Đúng:
            s = luồng.readline()
            nếu không thì:
                phá vỡ
            nếu tiến trình không phải  Không :
                (các) tiến trình, bối cảnh)
            khác:
                nếu không phải  self.verbose:
                    sys.stderr.write('.')
                khác:
                    sys.stderr.write(s.decode('utf-8'))
                sys.stderr.flush()
        luồng.close()

    def install_script(self, context, name, url):
        _, _, đường dẫn, _, _ = urlsplit(url)
        fn = os.path.split(path)[-1]
        binpath = bối cảnh.bin_path
        distpath = os.path.join(binpath, fn)
        tập lệnh # Download vào thư mục nhị phân của môi trường ảo
        urlretrieve(url, đường dẫn xa)
        tiến độ = self.progress
        nếu self.verbose:
            thuật ngữ = '\n'
        khác:
            hạn = ''
        nếu tiến trình không phải  Không :
            Progress('Đang cài đặt %s ...%s' % (tên, thuật ngữ), 'chính')
        khác:
            sys.stderr.write('Đang cài đặt %s ...%s' % (tên, thuật ngữ))
            sys.stderr.flush()
        # Install trong môi trường ảo
        args = [bối cảnh.env_exe, fn]
        p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)
        t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))
        t1.start()
        t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))
        t2.start()
        p.đợi()
        t1.join()
        t2.join()
        nếu tiến trình không phải  Không :
            tiến trình('xong.', 'chính')
        khác:
            sys.stderr.write('xong.\n')
        # Clean lên - không cần thiết nữa
        os.unlink(đường dẫn xa)

    def install_setuptools(tự, ngữ cảnh):
        """
        Cài đặt setuptools trong môi trường ảo.

        :param context: Thông tin về môi trường ảo
                        yêu cầu tạo đang được xử lý.
        """
        url = "https://bootstrap.pypa.io/ez_setup.py"
        self.install_script(ngữ cảnh, 'setuptools', url)
        # clear lên kho lưu trữ setuptools được tải xuống
        pred = lambda o: o.startswith('setuptools-')  o.endswith('.tar.gz')
        file = filter(pred, os.listdir(context.bin_path))
        cho f trong các tập tin:
            f = os.path.join(context.bin_path, f)
            os.unlink(f)

    def install_pip(tự, ngữ cảnh):
        """
        Cài đặt pip trong môi trường ảo.

        :param context: Thông tin về môi trường ảo
                        yêu cầu tạo đang được xử lý.
        """
        url = 'https://bootstrap.pypa.io/get-pip.py'
        self.install_script(ngữ cảnh, 'pip', url)


def chính(args=None):
    nhập khẩu argparse

    trình phân tích  pháp = argparse.ArgumentParser(prog=__name__,
                                     description='Tạo Python ảo '
                                                 'môi trường trong một hoặc'
                                                 'nhiều mục tiêu hơn'
                                                 'thư mục.')
    parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',
                        help='Thư mục để tạo '
                             'môi trường ảo.')
    Parser.add_argument('--no-setuptools', default=False,
                        action='store_true', dest='nodist',
                        help="Không cài đặt setuptools hoặc pip trong "
                             "môi trường ảo.")
    Parser.add_argument('--no-pip', default=False,
                        hành động='store_true', dest='nopip',
                        help="Không cài đặt pip trong ảo "
                             "môi trường.")
    Parser.add_argument('--system-site-packages', default=False,
                        action='store_true', dest='system_site',
                        help='Cấp cho môi trường ảo quyền truy cập vào '
                             'thư mục gói trang web hệ thống.')
    nếu os.name == 'nt':
        use_symlinks = Sai
    khác:
        use_symlinks = Đúng
    parser.add_argument('--symlinks', default=use_symlinks,
                        action='store_true', dest='symlinks',
                        help='Cố gắng sử dụng liên kết tượng trưng thay vì bản sao, '
                             'khi liên kết tượng trưng không phải là mặc định cho '
                             'nền tảng.')
    parser.add_argument('--clear', default=False, action='store_true',
                        dest='clear', help='Xóa nội dung của '
                                           'môi trường ảo'
                                           'thư mục nếu đã có'
                                           'tồn tại, trước ảo'
                                           'tạo môi trường.')
    parser.add_argument('--upgrade', default=False, action='store_true',
                        dest='nâng cấp', help='Nâng cấp ảo '
                                             'thư mục môi trường tới'
                                             'sử dụng phiên bản này'
                                             'Python, giả sử Python '
                                             'đã được nâng cấp'
                                             'tại chỗ.')
    parser.add_argument('--verbose', default=False, action='store_true',
                        dest='verbose', help='Hiển thị kết quả '
                                             'từ các kịch bản mà'
                                             'cài đặt setuptools và pip.')
    tùy chọn = trình phân tích  pháp.parse_args(args)
    nếu tùy chọn. nâng cấp  tùy chọn.clear:
        raise ValueError('bạn không thể cung cấp --upgrade và --clear cùng nhau.')
    builder = ExtendedEnvBuilder(system_site_packages=options.system_site,
                                   clear=options.clear,
                                   symlinks=options.symlinks,
                                   nâng cấp=options.upgrade,
                                   gật đầu=options.nodist,
                                   nopip=options.nopip,
                                   dài dòng=options.verbose)
    cho d trong options.dirs:
        builder.create(d)

nếu __name__ == '__main__':
    rc = 1
    thử:
        chính()
        RC = 0
    ngoại trừ Ngoại lệ  e:
        print('Lỗi: %s' % e, file=sys.stderr)
    sys.exit(rc)

Tập lệnh này cũng có sẵn để tải xuống online.