Browse Source
Co-authored-by: pr-submit[bot] <pr-submit[bot]@users.noreply.github.com> Co-authored-by: Yurii Motov <[email protected]> Co-authored-by: pr-push[bot] <pr-push[bot]@users.noreply.github.com>pull/14327/merge
committed by
GitHub
61 changed files with 369 additions and 1420 deletions
@ -6,9 +6,13 @@ |
|||||
|
|
||||
因此,通常会将它们提供为由应用程序读取的环境变量。 |
因此,通常会将它们提供为由应用程序读取的环境变量。 |
||||
|
|
||||
|
**环境变量**(也称为 **env var**)是存在于 Python 代码之外、操作系统中的值,可以由你的应用和其他程序读取。 |
||||
|
|
||||
|
你可以在运行命令时为该命令创建环境变量。你将在下面看到特定于平台的命令。 |
||||
|
|
||||
/// tip | 提示 |
/// tip | 提示 |
||||
|
|
||||
要理解环境变量,你可以阅读[环境变量](../environment-variables.md)。 |
阅读[环境变量指南](https://tiangolo.com/guides/environment-variables/)以详细了解环境变量的工作方式。 |
||||
|
|
||||
/// |
/// |
||||
|
|
||||
@ -20,16 +24,16 @@ |
|||||
|
|
||||
## Pydantic 的 `Settings` { #pydantic-settings } |
## Pydantic 的 `Settings` { #pydantic-settings } |
||||
|
|
||||
幸运的是,Pydantic 提供了一个很好的工具来处理来自环境变量的这些设置:[Pydantic:Settings 管理](https://docs.pydantic.dev/latest/concepts/pydantic_settings/)。 |
幸运的是,Pydantic 提供了一个很好的工具来处理来自环境变量的这些设置:[Pydantic:Settings 管理](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/)。 |
||||
|
|
||||
### 安装 `pydantic-settings` { #install-pydantic-settings } |
### 安装 `pydantic-settings` { #install-pydantic-settings } |
||||
|
|
||||
首先,确保你创建并激活了[虚拟环境](../virtual-environments.md),然后安装 `pydantic-settings` 包: |
将 `pydantic-settings` 包添加到你的项目: |
||||
|
|
||||
<div class="termy"> |
<div class="termy"> |
||||
|
|
||||
```console |
```console |
||||
$ pip install pydantic-settings |
$ uv add pydantic-settings |
||||
---> 100% |
---> 100% |
||||
``` |
``` |
||||
|
|
||||
@ -40,7 +44,7 @@ $ pip install pydantic-settings |
|||||
<div class="termy"> |
<div class="termy"> |
||||
|
|
||||
```console |
```console |
||||
$ pip install "fastapi[all]" |
$ uv add "fastapi[all]" |
||||
---> 100% |
---> 100% |
||||
``` |
``` |
||||
|
|
||||
@ -76,19 +80,39 @@ $ pip install "fastapi[all]" |
|||||
|
|
||||
接下来,运行服务器,并把配置作为环境变量传入,例如你可以设置 `ADMIN_EMAIL` 和 `APP_NAME`: |
接下来,运行服务器,并把配置作为环境变量传入,例如你可以设置 `ADMIN_EMAIL` 和 `APP_NAME`: |
||||
|
|
||||
|
//// tab | Linux, macOS, Windows Bash |
||||
|
|
||||
<div class="termy"> |
<div class="termy"> |
||||
|
|
||||
```console |
```console |
||||
$ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.py |
$ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" uv run fastapi run main.py |
||||
|
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
``` |
``` |
||||
|
|
||||
</div> |
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows PowerShell |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ $Env:ADMIN_EMAIL = "[email protected]" |
||||
|
$ $Env:APP_NAME = "ChimichangApp" |
||||
|
$ uv run fastapi run main.py |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
/// tip | 提示 |
/// tip | 提示 |
||||
|
|
||||
要为单个命令设置多个环境变量,只需用空格分隔它们,并把它们都放在命令前面。 |
在 Bash 中,要为单个命令设置多个环境变量,只需用空格分隔它们,并把它们都放在命令前面。 |
||||
|
|
||||
/// |
/// |
||||
|
|
||||
@ -172,11 +196,11 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p |
|||||
|
|
||||
/// |
/// |
||||
|
|
||||
Pydantic 支持使用一个外部库来从这类文件中读取。你可以在 [Pydantic Settings:Dotenv(.env)支持](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support) 中阅读更多信息。 |
Pydantic 支持使用一个外部库来从这类文件中读取。你可以在 [Pydantic Settings:Dotenv(.env)支持](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/#dotenv-env-support) 中阅读更多信息。 |
||||
|
|
||||
/// tip | 提示 |
/// tip | 提示 |
||||
|
|
||||
要使其工作,你需要执行 `pip install python-dotenv`。 |
要使其工作,请使用 `uv add python-dotenv` 将 `python-dotenv` 添加到你的项目。 |
||||
|
|
||||
/// |
/// |
||||
|
|
||||
@ -197,7 +221,7 @@ APP_NAME="ChimichangApp" |
|||||
|
|
||||
/// tip | 提示 |
/// tip | 提示 |
||||
|
|
||||
`model_config` 属性仅用于 Pydantic 配置。你可以在 [Pydantic:概念:配置](https://docs.pydantic.dev/latest/concepts/config/) 中阅读更多信息。 |
`model_config` 属性仅用于 Pydantic 配置。你可以在 [Pydantic:概念:配置](https://pydantic.dev/docs/validation/latest/concepts/config/) 中阅读更多信息。 |
||||
|
|
||||
/// |
/// |
||||
|
|
||||
|
|||||
@ -1,299 +1,11 @@ |
|||||
# 环境变量 { #environment-variables } |
# 环境变量 { #environment-variables } |
||||
|
|
||||
|
**环境变量**(也称为 **env var**)是一个独立于 Python 代码之外、存在于操作系统中的值,可以被你的应用程序和其他程序读取。 |
||||
|
|
||||
/// tip | 提示 |
FastAPI 应用程序通常使用环境变量进行配置,例如数据库 URL、电子邮件凭据和密钥。 |
||||
|
|
||||
如果你已经知道什么是“环境变量”并且知道如何使用它们,你可以放心跳过这一部分。 |
你将在[设置和环境变量](advanced/settings.md)中了解如何将它们用于应用程序配置。 |
||||
|
|
||||
/// |
## 了解更多 { #learn-more } |
||||
|
|
||||
环境变量(也称为“**env var**”)是一个独立于 Python 代码**之外**的变量,它存在于**操作系统**中,可以被你的 Python 代码(或其他程序)读取。 |
阅读[环境变量指南](https://tiangolo.com/guides/environment-variables/),了解详细的跨平台说明,包括如何创建和读取环境变量,以及 `PATH` 环境变量的工作方式。 |
||||
|
|
||||
环境变量对于处理应用程序**设置**、作为 Python **安装**的一部分等方面非常有用。 |
|
||||
|
|
||||
## 创建和使用环境变量 { #create-and-use-env-vars } |
|
||||
|
|
||||
你在 **shell(终端)**中就可以**创建**和使用环境变量,并不需要用到 Python: |
|
||||
|
|
||||
//// tab | Linux, macOS, Windows Bash |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
// 你可以使用以下命令创建一个名为 MY_NAME 的环境变量 |
|
||||
$ export MY_NAME="Wade Wilson" |
|
||||
|
|
||||
// 然后,你可以在其他程序中使用它,例如 |
|
||||
$ echo "Hello $MY_NAME" |
|
||||
|
|
||||
Hello Wade Wilson |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows PowerShell |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
// 创建一个名为 MY_NAME 的环境变量 |
|
||||
$ $Env:MY_NAME = "Wade Wilson" |
|
||||
|
|
||||
// 在其他程序中使用它,例如 |
|
||||
$ echo "Hello $Env:MY_NAME" |
|
||||
|
|
||||
Hello Wade Wilson |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
## 在 Python 中读取环境变量 { #read-env-vars-in-python } |
|
||||
|
|
||||
你也可以在 Python **之外**的终端中创建环境变量(或使用任何其他方法),然后在 Python 中**读取**它们。 |
|
||||
|
|
||||
例如,你可以创建一个名为 `main.py` 的文件,其中包含以下内容: |
|
||||
|
|
||||
```Python hl_lines="3" |
|
||||
import os |
|
||||
|
|
||||
name = os.getenv("MY_NAME", "World") |
|
||||
print(f"Hello {name} from Python") |
|
||||
``` |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
第二个参数是 [`os.getenv()`](https://docs.python.org/3.8/library/os.html#os.getenv) 的默认返回值。 |
|
||||
|
|
||||
如果没有提供,默认值为 `None`,这里我们提供 `"World"` 作为默认值。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
然后你可以调用这个 Python 程序: |
|
||||
|
|
||||
//// tab | Linux, macOS, Windows Bash |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
// 这里我们还没有设置环境变量 |
|
||||
$ python main.py |
|
||||
|
|
||||
// 因为我们没有设置环境变量,所以我们得到的是默认值 |
|
||||
|
|
||||
Hello World from Python |
|
||||
|
|
||||
// 但是如果我们事先创建过一个环境变量 |
|
||||
$ export MY_NAME="Wade Wilson" |
|
||||
|
|
||||
// 然后再次调用程序 |
|
||||
$ python main.py |
|
||||
|
|
||||
// 现在就可以读取到环境变量了 |
|
||||
|
|
||||
Hello Wade Wilson from Python |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows PowerShell |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
// 这里我们还没有设置环境变量 |
|
||||
$ python main.py |
|
||||
|
|
||||
// 因为我们没有设置环境变量,所以我们得到的是默认值 |
|
||||
|
|
||||
Hello World from Python |
|
||||
|
|
||||
// 但是如果我们事先创建过一个环境变量 |
|
||||
$ $Env:MY_NAME = "Wade Wilson" |
|
||||
|
|
||||
// 然后再次调用程序 |
|
||||
$ python main.py |
|
||||
|
|
||||
// 现在就可以读取到环境变量了 |
|
||||
|
|
||||
Hello Wade Wilson from Python |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
由于环境变量可以在代码之外设置、但可以被代码读取,并且不必与其他文件一起存储(提交到 `git`),因此通常用于配置或**设置**。 |
|
||||
|
|
||||
你还可以为**特定的程序调用**创建特定的环境变量,该环境变量仅对该程序可用,且仅在其运行期间有效。 |
|
||||
|
|
||||
要实现这一点,只需在同一行内、程序本身之前创建它: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
// 在这个程序调用的同一行中创建一个名为 MY_NAME 的环境变量 |
|
||||
$ MY_NAME="Wade Wilson" python main.py |
|
||||
|
|
||||
// 现在就可以读取到环境变量了 |
|
||||
|
|
||||
Hello Wade Wilson from Python |
|
||||
|
|
||||
// 在此之后这个环境变量将不会依然存在 |
|
||||
$ python main.py |
|
||||
|
|
||||
Hello World from Python |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
你可以在 [The Twelve-Factor App: 配置](https://12factor.net/config) 中了解更多信息。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 类型和验证 { #types-and-validation } |
|
||||
|
|
||||
这些环境变量只能处理**文本字符串**,因为它们是处于 Python 范畴之外的,必须与其他程序和操作系统的其余部分兼容(甚至与不同的操作系统兼容,如 Linux、Windows、macOS)。 |
|
||||
|
|
||||
这意味着从环境变量中读取的**任何值**在 Python 中都将是一个 `str`,任何类型转换或验证都必须在代码中完成。 |
|
||||
|
|
||||
你将在[高级用户指南 - 设置和环境变量](./advanced/settings.md)中了解更多关于使用环境变量处理**应用程序设置**的信息。 |
|
||||
|
|
||||
## `PATH` 环境变量 { #path-environment-variable } |
|
||||
|
|
||||
有一个**特殊的**环境变量称为 **`PATH`**,操作系统(Linux、macOS、Windows)用它来查找要运行的程序。 |
|
||||
|
|
||||
`PATH` 变量的值是一个长字符串,由 Linux 和 macOS 上的冒号 `:` 分隔的目录组成,而在 Windows 上则是由分号 `;` 分隔的。 |
|
||||
|
|
||||
例如,`PATH` 环境变量可能如下所示: |
|
||||
|
|
||||
//// tab | Linux, macOS |
|
||||
|
|
||||
```plaintext |
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin |
|
||||
``` |
|
||||
|
|
||||
这意味着系统应该在以下目录中查找程序: |
|
||||
|
|
||||
- `/usr/local/bin` |
|
||||
- `/usr/bin` |
|
||||
- `/bin` |
|
||||
- `/usr/sbin` |
|
||||
- `/sbin` |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows |
|
||||
|
|
||||
```plaintext |
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32 |
|
||||
``` |
|
||||
|
|
||||
这意味着系统应该在以下目录中查找程序: |
|
||||
|
|
||||
- `C:\Program Files\Python312\Scripts` |
|
||||
- `C:\Program Files\Python312` |
|
||||
- `C:\Windows\System32` |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
当你在终端中输入一个**命令**时,操作系统会在 `PATH` 环境变量中列出的**每个目录**中**查找**程序。 |
|
||||
|
|
||||
例如,当你在终端中输入 `python` 时,操作系统会在该列表中的**第一个目录**中查找名为 `python` 的程序。 |
|
||||
|
|
||||
如果找到了,那么操作系统将**使用它**;否则,操作系统会继续在**其他目录**中查找。 |
|
||||
|
|
||||
### 安装 Python 和更新 `PATH` { #installing-python-and-updating-the-path } |
|
||||
|
|
||||
安装 Python 时,可能会询问你是否要更新 `PATH` 环境变量。 |
|
||||
|
|
||||
//// tab | Linux, macOS |
|
||||
|
|
||||
假设你安装 Python 并最终将其安装在了目录 `/opt/custompython/bin` 中。 |
|
||||
|
|
||||
如果你同意更新 `PATH` 环境变量,那么安装程序将会将 `/opt/custompython/bin` 添加到 `PATH` 环境变量中。 |
|
||||
|
|
||||
它看起来大概会像这样: |
|
||||
|
|
||||
```plaintext |
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin |
|
||||
``` |
|
||||
|
|
||||
如此一来,当你在终端中输入 `python` 时,系统会在 `/opt/custompython/bin` 中找到 Python 程序(最后一个目录)并使用它。 |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows |
|
||||
|
|
||||
假设你安装 Python 并最终将其安装在了目录 `C:\opt\custompython\bin` 中。 |
|
||||
|
|
||||
如果你同意更新 `PATH` 环境变量,那么安装程序将会将 `C:\opt\custompython\bin` 添加到 `PATH` 环境变量中。 |
|
||||
|
|
||||
```plaintext |
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin |
|
||||
``` |
|
||||
|
|
||||
如此一来,当你在终端中输入 `python` 时,系统会在 `C:\opt\custompython\bin` 中找到 Python 程序(最后一个目录)并使用它。 |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
因此,如果你输入: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ python |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// tab | Linux, macOS |
|
||||
|
|
||||
系统会在 `/opt/custompython/bin` 中**找到** `python` 程序并运行它。 |
|
||||
|
|
||||
这和输入以下命令大致等价: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ /opt/custompython/bin/python |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows |
|
||||
|
|
||||
系统会在 `C:\opt\custompython\bin\python` 中**找到** `python` 程序并运行它。 |
|
||||
|
|
||||
这和输入以下命令大致等价: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ C:\opt\custompython\bin\python |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
当学习[虚拟环境](virtual-environments.md)时,这些信息将会很有用。 |
|
||||
|
|
||||
## 结论 { #conclusion } |
|
||||
|
|
||||
通过这个教程,你应该对**环境变量**是什么以及如何在 Python 中使用它们有了基本的了解。 |
|
||||
|
|
||||
你也可以在[环境变量 - 维基百科](https://en.wikipedia.org/wiki/Environment_variable)中了解更多关于它们的信息。 |
|
||||
|
|
||||
在许多情况下,环境变量的用途和适用性并不是很明显。但是在开发过程中,它们会在许多不同的场景中出现,因此了解它们是很有必要的。 |
|
||||
|
|
||||
例如,你将在下一节关于[虚拟环境](virtual-environments.md)中需要这些信息。 |
|
||||
|
|||||
@ -1,864 +1,35 @@ |
|||||
# 虚拟环境 { #virtual-environments } |
# 虚拟环境 { #virtual-environments } |
||||
|
|
||||
当你在 Python 工程中工作时,你可能会有必要用到一个**虚拟环境**(或类似的机制)来隔离你为每个工程安装的包。 |
当你在 Python 工程中工作时,你应该使用**虚拟环境**来隔离为每个工程安装的包。 |
||||
|
|
||||
/// note | 注意 |
对于 FastAPI 工程,我推荐使用 [uv](https://docs.astral.sh/uv/) 来管理工程、依赖项和虚拟环境。 |
||||
|
|
||||
如果你已经了解虚拟环境,知道如何创建和使用它们,你可以考虑跳过这一部分。🤓 |
## 创建工程 { #create-a-project } |
||||
|
|
||||
/// |
使用[官方安装指南](https://docs.astral.sh/uv/getting-started/installation/)安装 `uv`,然后创建一个工程: |
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
**虚拟环境**和**环境变量**是不同的。 |
|
||||
|
|
||||
**环境变量**是系统中的一个变量,可以被程序使用。 |
|
||||
|
|
||||
**虚拟环境**是一个包含一些文件的目录。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// note | 注意 |
|
||||
|
|
||||
这个页面将教你如何使用**虚拟环境**以及了解它们的工作原理。 |
|
||||
|
|
||||
如果你计划使用一个**可以为你管理一切的工具**(包括安装 Python),试试 [uv](https://github.com/astral-sh/uv)。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 创建一个工程 { #create-a-project } |
|
||||
|
|
||||
首先,为你的工程创建一个目录。 |
|
||||
|
|
||||
我通常会在我的主目录下创建一个名为 `code` 的目录。 |
|
||||
|
|
||||
在这个目录下,我再为每个工程创建一个目录。 |
|
||||
|
|
||||
<div class="termy"> |
<div class="termy"> |
||||
|
|
||||
```console |
```console |
||||
// 进入主目录 |
$ uv init awesome-project --bare |
||||
$ cd |
|
||||
// 创建一个用于存放所有代码工程的目录 |
|
||||
$ mkdir code |
|
||||
// 进入 code 目录 |
|
||||
$ cd code |
|
||||
// 创建一个用于存放这个工程的目录 |
|
||||
$ mkdir awesome-project |
|
||||
// 进入这个工程的目录 |
|
||||
$ cd awesome-project |
$ cd awesome-project |
||||
|
$ uv add "fastapi[standard]" |
||||
``` |
``` |
||||
|
|
||||
</div> |
</div> |
||||
|
|
||||
## 创建一个虚拟环境 { #create-a-virtual-environment } |
`uv` 会自动为工程创建虚拟环境。你不需要自己创建或激活虚拟环境。 |
||||
|
|
||||
在开始一个 Python 工程的**第一时间**,**<dfn title="还有其他做法,此处仅作一个简单的指南">在你的工程内部</dfn>**创建一个虚拟环境。 |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
你只需要 **在每个工程中操作一次**,而不是每次工作时都操作。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
//// tab | `venv` |
|
||||
|
|
||||
你可以使用 Python 自带的 `venv` 模块来创建一个虚拟环境。 |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ python -m venv .venv |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
/// details | 上述命令的含义 |
|
||||
|
|
||||
* `python`: 使用名为 `python` 的程序 |
|
||||
* `-m`: 以脚本的方式调用一个模块,我们将告诉它接下来使用哪个模块 |
|
||||
* `venv`: 使用名为 `venv` 的模块,这个模块通常随 Python 一起安装 |
|
||||
* `.venv`: 在新目录 `.venv` 中创建虚拟环境 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | `uv` |
|
||||
|
|
||||
如果你安装了 [`uv`](https://github.com/astral-sh/uv),你也可以使用它来创建一个虚拟环境。 |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ uv venv |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
默认情况下,`uv` 会在一个名为 `.venv` 的目录中创建一个虚拟环境。 |
|
||||
|
|
||||
但你可以通过传递一个额外的参数来自定义它,指定目录的名称。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
这个命令会在一个名为 `.venv` 的目录中创建一个新的虚拟环境。 |
|
||||
|
|
||||
/// details | `.venv`,或是其他名称 |
|
||||
|
|
||||
你可以在不同的目录下创建虚拟环境,但通常我们会把它命名为 `.venv`。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 激活虚拟环境 { #activate-the-virtual-environment } |
|
||||
|
|
||||
激活新的虚拟环境来确保你运行的任何 Python 命令或安装的包都能使用到它。 |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
**每次**开始一个 **新的终端会话** 来工作在这个工程时,你都需要执行这个操作。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
//// tab | Linux, macOS |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ source .venv/bin/activate |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows PowerShell |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ .venv\Scripts\Activate.ps1 |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows Bash |
|
||||
|
|
||||
或者,如果你在 Windows 上使用 Bash(例如 [Git Bash](https://gitforwindows.org/)): |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ source .venv/Scripts/activate |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
每次你在这个环境中安装一个 **新的包** 时,都需要 **重新激活** 这个环境。 |
|
||||
|
|
||||
这么做确保了当你使用一个由这个包安装的 **终端(<abbr title="command line interface - 命令行界面">CLI</abbr>)程序** 时,你使用的是你的虚拟环境中的程序,而不是全局安装、可能版本不同的程序。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 检查虚拟环境是否激活 { #check-the-virtual-environment-is-active } |
|
||||
|
|
||||
检查虚拟环境是否激活 (前面的命令是否生效)。 |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
这是 **可选的**,但这是一个很好的方法,可以 **检查** 一切是否按预期工作,以及你是否使用了你打算使用的虚拟环境。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
//// tab | Linux, macOS, Windows Bash |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ which python |
|
||||
|
|
||||
/home/user/code/awesome-project/.venv/bin/python |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
如果它显示了在你工程 (在这个例子中是 `awesome-project`) 的 `.venv/bin/python` 中的 `python` 二进制文件,那么它就生效了。🎉 |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows PowerShell |
使用 `uv run` 在工程环境中运行命令,例如: |
||||
|
|
||||
<div class="termy"> |
<div class="termy"> |
||||
|
|
||||
```console |
```console |
||||
$ Get-Command python |
$ uv run fastapi dev |
||||
|
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python |
|
||||
``` |
``` |
||||
|
|
||||
</div> |
</div> |
||||
|
|
||||
如果它显示了在你工程 (在这个例子中是 `awesome-project`) 的 `.venv\Scripts\python` 中的 `python` 二进制文件,那么它就生效了。🎉 |
## 了解更多 { #learn-more } |
||||
|
|
||||
//// |
|
||||
|
|
||||
## 升级 `pip` { #upgrade-pip } |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
如果你使用 [`uv`](https://github.com/astral-sh/uv) 来安装内容,而不是 `pip`,那么你就不需要升级 `pip`。😎 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
如果你使用 `pip` 来安装包(它是 Python 的默认组件),你应该将它 **升级** 到最新版本。 |
|
||||
|
|
||||
在安装包时出现的许多奇怪的错误都可以通过先升级 `pip` 来解决。 |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
通常你只需要在创建虚拟环境后 **执行一次** 这个操作。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
确保虚拟环境是激活的 (使用上面的命令),然后运行: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ python -m pip install --upgrade pip |
|
||||
|
|
||||
---> 100% |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
有时在尝试升级 pip 时,你可能会遇到 **`No module named pip`** 错误。 |
|
||||
|
|
||||
如果发生这种情况,使用下面的命令来安装并升级 pip: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ python -m ensurepip --upgrade |
|
||||
|
|
||||
---> 100% |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
该命令会在尚未安装 pip 时进行安装,并确保安装的 pip 版本不早于 `ensurepip` 提供的版本。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 添加 `.gitignore` { #add-gitignore } |
|
||||
|
|
||||
如果你使用 **Git** (这是你应该使用的),添加一个 `.gitignore` 文件来排除你的 `.venv` 中的所有内容。 |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
如果你使用 [`uv`](https://github.com/astral-sh/uv) 来创建虚拟环境,它会自动为你完成这个操作,你可以跳过这一步。😎 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
通常你只需要在创建虚拟环境后 **执行一次** 这个操作。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ echo "*" > .venv/.gitignore |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
/// details | 上述命令的含义 |
|
||||
|
|
||||
* `echo "*"`: 将在终端中 "打印" 文本 `*`(接下来的部分会对这个操作进行一些修改) |
|
||||
* `>`: 使左边的命令打印到终端的任何内容实际上都不会被打印,而是会被写入到右边的文件中 |
|
||||
* `.gitignore`: 被写入文本的文件的名称 |
|
||||
|
|
||||
而 `*` 对于 Git 来说意味着 "所有内容"。所以,它会忽略 `.venv` 目录中的所有内容。 |
|
||||
|
|
||||
该命令会创建一个名为 `.gitignore` 的文件,内容如下: |
|
||||
|
|
||||
```gitignore |
|
||||
* |
|
||||
``` |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 安装软件包 { #install-packages } |
|
||||
|
|
||||
在激活虚拟环境后,你可以在其中安装软件包。 |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
当你需要安装或升级软件包时,执行本操作**一次**; |
|
||||
|
|
||||
如果你需要再升级版本或添加新软件包,你可以**再次执行此操作**。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### 直接安装包 { #install-packages-directly } |
|
||||
|
|
||||
如果你急于安装,不想使用文件来声明工程的软件包依赖,你可以直接安装它们。 |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
将程序所需的软件包及其版本放在文件中(例如 `requirements.txt` 或 `pyproject.toml`)是个好(并且非常好)的主意。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
//// tab | `pip` |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ pip install "fastapi[standard]" |
|
||||
|
|
||||
---> 100% |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | `uv` |
|
||||
|
|
||||
如果你有 [`uv`](https://github.com/astral-sh/uv): |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ uv pip install "fastapi[standard]" |
|
||||
---> 100% |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
### 从 `requirements.txt` 安装 { #install-from-requirements-txt } |
|
||||
|
|
||||
如果你有一个 `requirements.txt` 文件,你可以使用它来安装其中的软件包。 |
|
||||
|
|
||||
//// tab | `pip` |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ pip install -r requirements.txt |
|
||||
---> 100% |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | `uv` |
|
||||
|
|
||||
如果你有 [`uv`](https://github.com/astral-sh/uv): |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ uv pip install -r requirements.txt |
|
||||
---> 100% |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
/// details | 关于 `requirements.txt` |
|
||||
|
|
||||
一个包含一些软件包的 `requirements.txt` 文件看起来应该是这样的: |
|
||||
|
|
||||
```requirements.txt |
|
||||
fastapi[standard]==0.113.0 |
|
||||
pydantic==2.8.0 |
|
||||
``` |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 运行程序 { #run-your-program } |
|
||||
|
|
||||
在你激活虚拟环境后,你可以运行你的程序,它将使用虚拟环境中的 Python 和你在其中安装的软件包。 |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ python main.py |
|
||||
|
|
||||
Hello World |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
## 配置编辑器 { #configure-your-editor } |
|
||||
|
|
||||
你可能会用到编辑器,请确保配置它使用与你创建的相同的虚拟环境(它可能会自动检测到),以便你可以获得自动补全和内联错误提示。 |
|
||||
|
|
||||
例如: |
|
||||
|
|
||||
* [VS Code](https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment) |
|
||||
* [PyCharm](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html) |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
通常你只需要在创建虚拟环境时执行此操作**一次**。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 退出虚拟环境 { #deactivate-the-virtual-environment } |
|
||||
|
|
||||
当你完成工作后,你可以**退出**虚拟环境。 |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ deactivate |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
这样,当你运行 `python` 时,它不会尝试从那个虚拟环境及其已安装的软件包中运行。 |
|
||||
|
|
||||
## 开始工作 { #ready-to-work } |
|
||||
|
|
||||
现在你已经准备好开始你的工作了。 |
|
||||
|
|
||||
|
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
你想要理解上面的所有内容吗? |
|
||||
|
|
||||
继续阅读。👇🤓 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 为什么要使用虚拟环境 { #why-virtual-environments } |
|
||||
|
|
||||
你需要安装 [Python](https://www.python.org/) 才能使用 FastAPI。 |
|
||||
|
|
||||
之后,你需要**安装** FastAPI 和你想要使用的任何其他**软件包**。 |
|
||||
|
|
||||
要安装软件包,你通常会使用随 Python 一起提供的 `pip` 命令(或类似的替代方案)。 |
|
||||
|
|
||||
然而,如果你直接使用 `pip`,软件包将被安装在你的**全局 Python 环境**中(即 Python 的全局安装)。 |
|
||||
|
|
||||
### 存在的问题 { #the-problem } |
|
||||
|
|
||||
那么,在全局 Python 环境中安装软件包有什么问题呢? |
|
||||
|
|
||||
有些时候,你可能会编写许多不同的程序,这些程序依赖于**不同的软件包**;你所做的一些工程也会依赖于**同一软件包的不同版本**。😱 |
|
||||
|
|
||||
例如,你可能会创建一个名为 `philosophers-stone` 的工程,这个程序依赖于另一个名为 **`harry` 的软件包,使用版本 `1`**。因此,你需要安装 `harry`。 |
|
||||
|
|
||||
```mermaid |
|
||||
flowchart LR |
|
||||
stone(philosophers-stone) -->|需要| harry-1[harry v1] |
|
||||
``` |
|
||||
|
|
||||
然而在此之后,你又创建了另一个名为 `prisoner-of-azkaban` 的工程,这个工程也依赖于 `harry`,但是这个工程需要 **`harry` 版本 `3`**。 |
|
||||
|
|
||||
```mermaid |
|
||||
flowchart LR |
|
||||
azkaban(prisoner-of-azkaban) --> |需要| harry-3[harry v3] |
|
||||
``` |
|
||||
|
|
||||
那么现在的问题是,如果你将软件包安装在全局环境中而不是在本地**虚拟环境**中,你将不得不面临选择安装哪个版本的 `harry` 的问题。 |
|
||||
|
|
||||
如果你想运行 `philosophers-stone`,你需要首先安装 `harry` 版本 `1`,例如: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ pip install "harry==1" |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
然后你将在全局 Python 环境中安装 `harry` 版本 `1`。 |
|
||||
|
|
||||
```mermaid |
|
||||
flowchart LR |
|
||||
subgraph global[全局环境] |
|
||||
harry-1[harry v1] |
|
||||
end |
|
||||
subgraph stone-project[工程 philosophers-stone] |
|
||||
stone(philosophers-stone) -->|需要| harry-1 |
|
||||
end |
|
||||
``` |
|
||||
|
|
||||
但是如果你想运行 `prisoner-of-azkaban`,你需要卸载 `harry` 版本 `1` 并安装 `harry` 版本 `3`(或者说,只要你安装版本 `3` ,版本 `1` 就会自动卸载)。 |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ pip install "harry==3" |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
于是,你在你的全局 Python 环境中安装了 `harry` 版本 `3`。 |
|
||||
|
|
||||
如果你再次尝试运行 `philosophers-stone`,有可能它**无法正常工作**,因为它需要 `harry` 版本 `1`。 |
|
||||
|
|
||||
```mermaid |
|
||||
flowchart LR |
|
||||
subgraph global[全局环境] |
|
||||
harry-1[<strike>harry v1</strike>] |
|
||||
style harry-1 fill:#ccc,stroke-dasharray: 5 5 |
|
||||
harry-3[harry v3] |
|
||||
end |
|
||||
subgraph stone-project[工程 philosophers-stone] |
|
||||
stone(philosophers-stone) -.-x|⛔️| harry-1 |
|
||||
end |
|
||||
subgraph azkaban-project[工程 prisoner-of-azkaban] |
|
||||
azkaban(prisoner-of-azkaban) --> |需要| harry-3 |
|
||||
end |
|
||||
``` |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
Python 包在推出**新版本**时通常会尽量**避免破坏性更改**,但最好还是要小心,要想清楚再安装新版本,而且在运行测试以确保一切能正常工作时再安装。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
现在,想象一下,如果有**许多**其他**软件包**,它们都是你的**工程所依赖的**。这是非常难以管理的。你可能会发现,有些工程使用了一些**不兼容的软件包版本**,而不知道为什么某些东西无法正常工作。 |
|
||||
|
|
||||
此外,取决于你的操作系统(例如 Linux、Windows、macOS),它可能已经预先安装了 Python。在这种情况下,它可能已经预先安装了一些软件包,这些软件包的特定版本是**系统所需的**。如果你在全局 Python 环境中安装软件包,你可能会**破坏**一些随操作系统一起安装的程序。 |
|
||||
|
|
||||
## 软件包安装在哪里 { #where-are-packages-installed } |
|
||||
|
|
||||
当你安装 Python 时,它会在你的计算机上创建一些目录,并在这些目录中放一些文件。 |
|
||||
|
|
||||
其中一些目录负责存放你安装的所有软件包。 |
|
||||
|
|
||||
当你运行: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
// 先别去运行这个命令,这只是一个示例 🤓 |
|
||||
$ pip install "fastapi[standard]" |
|
||||
---> 100% |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
这将会从 [PyPI](https://pypi.org/project/fastapi/) 下载一个压缩文件,其中包含 FastAPI 代码。 |
|
||||
|
|
||||
它还会**下载** FastAPI 依赖的其他软件包的文件。 |
|
||||
|
|
||||
然后它会**解压**所有这些文件,并将它们放在你的计算机上的一个目录中。 |
|
||||
|
|
||||
默认情况下,它会将下载并解压的这些文件放在随 Python 安装的目录中,这就是**全局环境**。 |
|
||||
|
|
||||
## 什么是虚拟环境 { #what-are-virtual-environments } |
|
||||
|
|
||||
解决软件包都安装在全局环境中的问题的方法是为你所做的每个工程使用一个**虚拟环境**。 |
|
||||
|
|
||||
虚拟环境是一个**目录**,与全局环境非常相似,你可以在其中专为某个工程安装软件包。 |
|
||||
|
|
||||
这样,每个工程都会有自己的虚拟环境(`.venv` 目录),其中包含自己的软件包。 |
|
||||
|
|
||||
```mermaid |
|
||||
flowchart TB |
|
||||
subgraph stone-project[工程 philosophers-stone] |
|
||||
stone(philosophers-stone) --->|需要| harry-1 |
|
||||
subgraph venv1[.venv] |
|
||||
harry-1[harry v1] |
|
||||
end |
|
||||
end |
|
||||
subgraph azkaban-project[工程 prisoner-of-azkaban] |
|
||||
azkaban(prisoner-of-azkaban) --->|需要| harry-3 |
|
||||
subgraph venv2[.venv] |
|
||||
harry-3[harry v3] |
|
||||
end |
|
||||
end |
|
||||
stone-project ~~~ azkaban-project |
|
||||
``` |
|
||||
|
|
||||
## 激活虚拟环境意味着什么 { #what-does-activating-a-virtual-environment-mean } |
|
||||
|
|
||||
当你激活了一个虚拟环境,例如: |
|
||||
|
|
||||
//// tab | Linux, macOS |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ source .venv/bin/activate |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows PowerShell |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ .venv\Scripts\Activate.ps1 |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows Bash |
|
||||
|
|
||||
或者如果你在 Windows 上使用 Bash(例如 [Git Bash](https://gitforwindows.org/)): |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ source .venv/Scripts/activate |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
这个命令会创建或修改一些[环境变量](environment-variables.md),这些环境变量将在接下来的命令中可用。 |
|
||||
|
|
||||
其中之一是 `PATH` 变量。 |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
你可以在 [环境变量](environment-variables.md#path-environment-variable) 部分了解更多关于 `PATH` 环境变量的内容。 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
激活虚拟环境会将其路径 `.venv/bin`(在 Linux 和 macOS 上)或 `.venv\Scripts`(在 Windows 上)添加到 `PATH` 环境变量中。 |
|
||||
|
|
||||
假设在激活环境之前,`PATH` 变量看起来像这样: |
|
||||
|
|
||||
//// tab | Linux, macOS |
|
||||
|
|
||||
```plaintext |
|
||||
/usr/bin:/bin:/usr/sbin:/sbin |
|
||||
``` |
|
||||
|
|
||||
这意味着系统会在以下目录中查找程序: |
|
||||
|
|
||||
* `/usr/bin` |
|
||||
* `/bin` |
|
||||
* `/usr/sbin` |
|
||||
* `/sbin` |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows |
|
||||
|
|
||||
```plaintext |
|
||||
C:\Windows\System32 |
|
||||
``` |
|
||||
|
|
||||
这意味着系统会在以下目录中查找程序: |
|
||||
|
|
||||
* `C:\Windows\System32` |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
激活虚拟环境后,`PATH` 变量会变成这样: |
|
||||
|
|
||||
//// tab | Linux, macOS |
|
||||
|
|
||||
```plaintext |
|
||||
/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin |
|
||||
``` |
|
||||
|
|
||||
这意味着系统现在会首先在以下目录中查找程序: |
|
||||
|
|
||||
```plaintext |
|
||||
/home/user/code/awesome-project/.venv/bin |
|
||||
``` |
|
||||
|
|
||||
然后再在其他目录中查找。 |
|
||||
|
|
||||
因此,当你在终端中输入 `python` 时,系统会在以下目录中找到 Python 程序: |
|
||||
|
|
||||
```plaintext |
|
||||
/home/user/code/awesome-project/.venv/bin/python |
|
||||
``` |
|
||||
|
|
||||
并使用这个。 |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows |
|
||||
|
|
||||
```plaintext |
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32 |
|
||||
``` |
|
||||
|
|
||||
这意味着系统现在会首先在以下目录中查找程序: |
|
||||
|
|
||||
```plaintext |
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts |
|
||||
``` |
|
||||
|
|
||||
然后再在其他目录中查找。 |
|
||||
|
|
||||
因此,当你在终端中输入 `python` 时,系统会在以下目录中找到 Python 程序: |
|
||||
|
|
||||
```plaintext |
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python |
|
||||
``` |
|
||||
|
|
||||
并使用这个。 |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
一个重要的细节是,虚拟环境路径会被放在 `PATH` 变量的**开头**。系统会在找到任何其他可用的 Python **之前**找到它。这样,当你运行 `python` 时,它会使用**虚拟环境中**的 Python,而不是任何其他 `python`(例如,全局环境中的 `python`)。 |
|
||||
|
|
||||
激活虚拟环境还会改变其他一些东西,但这是它所做的最重要的事情之一。 |
|
||||
|
|
||||
## 检查虚拟环境 { #checking-a-virtual-environment } |
|
||||
|
|
||||
当你检查虚拟环境是否激活时,例如: |
|
||||
|
|
||||
//// tab | Linux, macOS, Windows Bash |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ which python |
|
||||
|
|
||||
/home/user/code/awesome-project/.venv/bin/python |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | Windows PowerShell |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ Get-Command python |
|
||||
|
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
这意味着将使用的 `python` 程序是**在虚拟环境中**的那个。 |
|
||||
|
|
||||
在 Linux 和 macOS 中使用 `which`,在 Windows PowerShell 中使用 `Get-Command`。 |
|
||||
|
|
||||
这个命令的工作方式是,它会在 `PATH` 环境变量中查找,按顺序**逐个路径**查找名为 `python` 的程序。一旦找到,它会**显示该程序的路径**。 |
|
||||
|
|
||||
最重要的部分是,当你调用 `python` 时,将执行的就是这个确切的 "`python`"。 |
|
||||
|
|
||||
因此,你可以确认你是否在正确的虚拟环境中。 |
|
||||
|
|
||||
/// tip | 提示 |
|
||||
|
|
||||
激活一个虚拟环境,获取一个 Python,然后**转到另一个工程**是一件很容易的事情; |
|
||||
|
|
||||
但如果第二个工程**无法工作**,那是因为你使用了来自另一个工程的虚拟环境的、**不正确的 Python**。 |
|
||||
|
|
||||
因此,会检查正在使用的 `python` 是很有用的。🤓 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 为什么要停用虚拟环境 { #why-deactivate-a-virtual-environment } |
|
||||
|
|
||||
例如,你可能正在一个工程 `philosophers-stone` 上工作,**激活了该虚拟环境**,安装了包并使用了该环境, |
|
||||
|
|
||||
然后你想要在**另一个工程** `prisoner-of-azkaban` 上工作, |
|
||||
|
|
||||
你进入那个工程: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ cd ~/code/prisoner-of-azkaban |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
如果你不去停用 `philosophers-stone` 的虚拟环境,当你在终端中运行 `python` 时,它会尝试使用 `philosophers-stone` 中的 Python。 |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ cd ~/code/prisoner-of-azkaban |
|
||||
|
|
||||
$ python main.py |
|
||||
|
|
||||
// 导入 sirius 报错,它没有安装 😱 |
|
||||
Traceback (most recent call last): |
|
||||
File "main.py", line 1, in <module> |
|
||||
import sirius |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
但是如果你停用虚拟环境并激活 `prisoner-of-azkaban` 的新虚拟环境,那么当你运行 `python` 时,它会使用 `prisoner-of-azkaban` 中的虚拟环境中的 Python。 |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ cd ~/code/prisoner-of-azkaban |
|
||||
|
|
||||
// 你不需要在旧目录中操作停用,你可以在任何地方操作停用,甚至在转到另一个工程之后 😎 |
|
||||
$ deactivate |
|
||||
|
|
||||
// 激活 prisoner-of-azkaban/.venv 中的虚拟环境 🚀 |
|
||||
$ source .venv/bin/activate |
|
||||
|
|
||||
// 现在当你运行 python 时,它会在这个虚拟环境中找到安装的 sirius 包 ✨ |
|
||||
$ python main.py |
|
||||
|
|
||||
I solemnly swear 🐺 |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
## 替代方案 { #alternatives } |
|
||||
|
|
||||
这是一个简单的指南,可以帮助你入门并教会你如何理解一切**底层**的东西。 |
|
||||
|
|
||||
有许多**替代方案**来管理虚拟环境、包依赖(requirements)、工程。 |
|
||||
|
|
||||
一旦你准备好并想要使用一个工具来**管理整个工程**、包依赖、虚拟环境等,建议你尝试 [uv](https://github.com/astral-sh/uv)。 |
|
||||
|
|
||||
`uv` 可以做很多事情,它可以: |
|
||||
|
|
||||
* 为你**安装 Python**,包括不同的版本 |
|
||||
* 为你的工程管理**虚拟环境** |
|
||||
* 安装**软件包** |
|
||||
* 为你的工程管理软件包的**依赖和版本** |
|
||||
* 确保你有一个**确切**的软件包和版本集合来安装,包括它们的依赖项,这样你就可以确保在生产中运行你的工程与在开发时在你的计算机上运行的工程完全相同,这被称为**锁定** |
|
||||
* 还有很多其他功能 |
|
||||
|
|
||||
## 结论 { #conclusion } |
|
||||
|
|
||||
如果你读过并理解了所有这些,现在**你对虚拟环境的了解比很多开发者都要多**。🤓 |
|
||||
|
|
||||
在未来当你调试看起来复杂的东西时,了解这些细节很可能会有用,你会知道**它是如何在底层工作的**。😎 |
阅读[虚拟环境指南](https://tiangolo.com/guides/virtual-environments/)以了解虚拟环境在底层是如何工作的,包括激活以及替代的 `python -m venv` 和 `pip` 工作流。 |
||||
|
|||||
Loading…
Reference in new issue