跳到内容

创建项目

uv 支持使用 uv init 创建项目。

创建项目时,uv 支持两种基本模板:应用程序 (applications)库 (libraries)。默认情况下,uv 会创建一个应用程序项目。可以使用 --lib 标志来创建库项目。

目标目录

uv 将在当前工作目录中创建项目,或者通过提供名称(例如 uv init foo)在目标目录中创建。工作目录可以通过 --directory 选项进行修改,这将使目标目录路径被解释为相对于指定的工作目录。如果目标目录中已经存在项目(即存在 pyproject.toml),uv 将报错并退出。

应用程序

应用程序项目适用于 Web 服务器、脚本和命令行界面。

应用程序是 uv init 的默认目标,也可以通过 --app 标志显式指定。

$ uv init example-app

该项目包含一个 pyproject.toml、一个示例文件 (main.py)、一个自述文件 (readme) 以及一个 Python 版本锁定文件 (.python-version)。

$ tree example-app
example-app
├── .python-version
├── README.md
├── main.py
└── pyproject.toml

注意

在 v0.6.0 之前,uv 创建的文件名为 hello.py 而不是 main.py

pyproject.toml 包含基本的元数据。它不包含构建系统,不是一个 包 (package),也不会被安装到环境中。

pyproject.toml
[project]
name = "example-app"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []

示例文件定义了一个包含标准样板代码的 main 函数。

main.py
def main():
    print("Hello from example-app!")


if __name__ == "__main__":
    main()

可以使用 uv run 执行 Python 文件。

$ cd example-app
$ uv run main.py
Hello from example-project!

打包的应用程序

许多用例需要一个 。例如,如果你正在创建一个将发布到 PyPI 的命令行界面,或者想在专用目录中定义测试。

可以使用 --package 标志来创建打包的应用程序。

$ uv init --package example-pkg

源代码被移动到 src 目录中,包含一个模块目录和一个 __init__.py 文件。

$ tree example-pkg
example-pkg
├── .python-version
├── README.md
├── pyproject.toml
└── src
    └── example_pkg
        └── __init__.py

定义了一个 构建系统,因此项目将被安装到环境中。

pyproject.toml
[project]
name = "example-pkg"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []

[project.scripts]
example-pkg = "example_pkg:main"

[build-system]
requires = ["uv_build>=0.10.9,<0.11.0"]
build-backend = "uv_build"

提示

可以使用 --build-backend 选项来请求替代的构建系统。

包含了一个 命令 (command) 定义。

pyproject.toml
[project]
name = "example-pkg"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []

[project.scripts]
example-pkg = "example_pkg:main"

[build-system]
requires = ["uv_build>=0.10.9,<0.11.0"]
build-backend = "uv_build"

该命令可以使用 uv run 执行。

$ cd example-pkg
$ uv run example-pkg
Hello from example-pkg!

库为其他项目提供函数和对象。库旨在被构建和分发,例如通过上传到 PyPI。

可以使用 --lib 标志创建库。

$ uv init --lib example-lib

注意

使用 --lib 隐含了 --package。库始终需要作为打包项目。

打包的应用程序 一样,使用了 src 布局。包含一个 py.typed 标记,以向使用者表明可以从该库中读取类型信息。

$ tree example-lib
example-lib
├── .python-version
├── README.md
├── pyproject.toml
└── src
    └── example_lib
        ├── py.typed
        └── __init__.py

注意

在开发库时,src 布局特别有价值。它确保库与项目根目录中的任何 python 调用相隔离,并确保分发的库代码与项目其余的源代码良好分离。

定义了一个 构建系统,因此项目将被安装到环境中。

pyproject.toml
[project]
name = "example-lib"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []

[build-system]
requires = ["uv_build>=0.10.9,<0.11.0"]
build-backend = "uv_build"

提示

你可以通过 --build-backend 选择不同的构建后端模板,可选值包括 hatchlinguv_buildflit-corepdm-backendsetuptoolsmaturinscikit-build-core。如果你想创建 带有扩展模块的库,则需要使用替代的后端。

创建的模块定义了一个简单的 API 函数。

__init__.py
def hello() -> str:
    return "Hello from example-lib!"

你可以使用 uv run 导入并执行它。

$ cd example-lib
$ uv run python -c "import example_lib; print(example_lib.hello())"
Hello from example-lib!

带有扩展模块的项目

大多数 Python 项目都是“纯 Python”的,这意味着它们不会定义使用 C、C++、FORTRAN 或 Rust 等其他语言编写的模块。然而,带有扩展模块的项目通常用于性能敏感的代码。

创建带有扩展模块的项目需要选择替代的构建系统。uv 支持使用以下支持构建扩展模块的构建系统创建项目:

  • maturin 用于包含 Rust 代码的项目。
  • scikit-build-core 用于包含 C、C++、FORTRAN、Cython 代码的项目。

使用 --build-backend 标志指定构建系统。

$ uv init --build-backend maturin example-ext

注意

使用 --build-backend 隐含了 --package

除了典型的 Python 项目文件外,该项目还包含 Cargo.tomllib.rs 文件。

$ tree example-ext
example-ext
├── .python-version
├── Cargo.toml
├── README.md
├── pyproject.toml
└── src
    ├── lib.rs
    └── example_ext
        ├── __init__.py
        └── _core.pyi

注意

如果使用 scikit-build-core,你将看到 CMake 配置和一个 main.cpp 文件。

Rust 库定义了一个简单的函数。

src/lib.rs
use pyo3::prelude::*;

#[pymodule]
mod _core {
    use pyo3::prelude::*;

    #[pyfunction]
    fn hello_from_bin() -> String {
        "Hello from example-ext!".to_string()
    }
}

Python 模块导入了它。

src/example_ext/__init__.py
from example_ext._core import hello_from_bin


def main() -> None:
    print(hello_from_bin())

该命令可以使用 uv run 执行。

$ cd example-ext
$ uv run example-ext
Hello from example-ext!

重要

当使用 maturin 或 scikit-build-core 创建项目时,uv 会配置 tool.uv.cache-keys 以包含常见源代码文件类型。要强制重新构建(例如在修改 cache-keys 之外的文件时,或不使用 cache-keys 时),请使用 --reinstall

创建最小化项目

如果你只想创建一个 pyproject.toml,请使用 --bare 选项。

$ uv init example --bare

uv 将跳过创建 Python 版本锁定文件、README 以及任何源代码目录或文件。此外,uv 不会初始化版本控制系统(即 git)。

$ tree example-bare
example-bare
└── pyproject.toml

uv 也不会向 pyproject.toml 添加额外的元数据,例如 descriptionauthors

[project]
name = "example"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []

--bare 选项可以与其他选项(如 --lib--build-backend)一起使用——在这种情况下,uv 仍然会配置构建系统,但不会创建预期的文件结构。

当使用 --bare 时,仍然可以选择性地使用其他功能。

$ uv init example --bare --description "Hello world" --author-from git --vcs git --python-pin