项目管理

uv 的项目管理功能更多的借鉴了 Rust 中 Cargo 工具的项目管理理念。但主要区别是 uv 是通过项目目录中的pyproject.toml文件来完成项目管理的。

新项目创建

新项目的创建主要是通过uv init命令。

如果当前没有项目的目录那么可以通过命令uv init <project-name>来创建一个目录,uv 会在当前目录中创建一个名为project-name的目录,并在其中创建一个项目所需要使用的基础文件。如果已经完成了项目目录的创建,那么可以cd到这个目录中,直接使用不带任何参数的uv init命令来在当前目录中创建项目所使用的文件来初始化一个项目。

un init命令会在项目目录中创建以下四个文件:

  • .python-version,项目所使用 Python 版本说明文件,这个文件将控制 uv 如何创建项目运行所需的虚拟环境。
  • README.md,项目说明文件。
  • main.py,项目主文件。
  • pyproject.toml,项目元信息描述以及项目依赖声明文件。

在执行uv runuv sync等命令以后,项目的目录中还将可能出现以下文件和目录:

  • uv.lock,用于精确定义所需安装依赖版本的快平台锁定文件,这个文件通常由 uv 自动生成且不需要手工编辑。
  • .venv,存放 Python 虚拟环境的目录。

pyproject.toml文件中的元信息

pyproject.toml文件的常见内容主要是以下形式的:

[project]
name = "project-name"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
dependencies = []

pyproject.toml中,常用的顶级配置组有三个,分别是:[build-system][project][tool]

其中[build-system]是比较建议配置的,它的作用主要是用来指定项目所使用的编译发布工具。[project]就是pyproject.toml在生成的时候自动为我们填写的部分了,它主要声明了关于项目的一些元信息。[tool]是用来定义项目中需要使用到的一些工具的配置的。

对于平时使用的 pip 等工具来说,是无法将 Python 项目的源码制作成分发包(distribution package),要制作分发包则需要使用 Hatchling、Setuptools 等工具,这些工具的使用就需要在[build-system]中配置。[build-system]中有两个配置项:requiresbuild-backend,分别用来设置所依赖的编译后端及其版本和用执行编译的 Python 对象名称。例如要使用 Setuptools,就可以如同以下示例一样配置。

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

最常编写的部分就是[project]部分了。以下是这部分内容中常用的配置项:

  • name,项目的名称,同时也是项目发布到 PyPI 的时候要使用的名称。
  • version,项目当前的版本。这个配置项通常更加倾向于使用动态生成的值,也就是配置dynamic = ["version"]来使编译后端通过设定__version__来动态填写这个内容。
  • authors,参与项目开发的作者名单,列表形式,其中每个元素可使用name来设定作者的名字,email来设定作者的电子邮箱。
  • description,项目的介绍。
  • readme,项目的说明文件。
  • requires-python,当前项目所需的 Python 版本,可以使用类似`>=3.9“的表达式定义。
  • claassifiers,用于索引包的额外配置元信息。
  • license,项目的授权方式。
  • license-files,项目的授权说明文件。
  • urls,在 PyPI 上需要列出来的附加链接。

[project]部分最重要的配置项目就是dependenciesoptional-dependencies,它们分别用于配置项目的必备依赖和可选依赖。这两种依赖在pyproject.toml中的配置方式是相同的,通过[project]下的dependenciesoptional-dependencies配置项来通过列举一个列表配置,此外就是optional-dependencies还可以通过[project.optional-dependencies]来通过字典的形式配置。以下通过两个示例来分别展示一下两种配置方式的异同。

[project]
dynamic = ["version"]
name = "example-project"
dependencies = [
    "httpx",
    "django>2.1"
]

使用在dependencies中用来表达依赖项目的字符串,需要符合 PEP 508 的规则要求。这种字符串在requirements.txt中使用广泛。

运行项目

命令uv run可以用来执行当前项目环境中的脚本或者命令。例如上一节中创建的项目,就可以使用uv run main.py来运行。

如果要运行其他命令,例如直接启动 Flask,可以执行命令uv run -- flask run -p 8000。两个连词符后面即是uv run要执行的命令。

uv run在开始运行指定命令和脚本之前,会将uv.lock文件中记录的依赖与pyproject.toml中记录的项目依赖做对比和更新,并保证环境与uv.lock文件中的记录一致。

如果需要指定项目运行所需的 Python 版本,那么可以附加--python命令并指明所需要的 Python 版本。

Tip

如果项目目录中已经创建了虚拟环境,那么可以向uv run命令添加--active参数来指示uv run优先使用项目的虚拟环境来运行,而不是创建一个临时的独立环境中运行。

项目编译与发布

命令uv build可以完成源码发布包和二进制发布包的编译,默认情况下,uv 会将编译打包好的内容放置在项目的dist目录下。

编译打包好的内容则可以通过命令uv publish发布到 PyPI。