尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Typer:基于 Python 类型提示构建现代 CLI 应用的完整入门与实践指南

Typer:基于 Python 类型提示构建现代 CLI 应用的完整入门与实践指南 Typer基于 Python 类型提示构建现代 CLI 应用的完整入门与实践指南【免费下载链接】typerTyper, build great CLIs. Easy to code. Based on Python type hints.项目地址: https://gitcode.com/GitHub_Trending/ty/typerTyper 是一个专为构建 CLI命令行界面应用而设计的 Python 库它让开发者乐于编写、让终端用户乐于使用命令行程序。本指南以当前仓库Typer 0.27.1的 README.md 为主线结合 typer/main.py、typer/cli.py、typer/params.py 等源码与测试完整讲解从安装、零代码改造普通脚本、到用typer.run()和typer.Typer()构建多子命令应用的完整路径并深入剖析其类型提示即 CLI 声明的底层原理。读完本文你将掌握 Typer 的核心用法、自动帮助与自动补全机制以及它在当前版本中的依赖构成与关键行为。什么是 TyperFastAPI 的 CLI 孪生兄弟Typer 的核心定位是仅靠标准的 Python 类型提示type hints声明函数参数就能自动生成完整的 CLI 应用——包括参数解析、校验、帮助文本和终端补全。正如 README 所述Typer 是 FastAPI 的小兄弟被称为CLI 界的 FastAPIFastAPI 用类型提示构建 Web APITyper 用类型提示构建命令行应用两者共享由标准类型声明驱动、自动生成交互能力的设计哲学。README 中总结的五大关键特性特性说明Intuitive to write直观易写极佳的编辑器支持随处补全减少调试时间上手成本低Easy to use对用户易用自动生成--help为所有主流 Shell 提供自动补全Short代码简短最小化重复代码一次参数声明获得多种能力更少 BugStart simple简单起步最简单的示例只需在你的应用中加2 行代码1 个 import、1 次函数调用Grow large随需扩展可以无限增加复杂度构建任意复杂的命令树和子命令组此外Typer 还自带一个typer命令行程序由 pyproject.toml 中的typer typer.cli:main注册为入口可以直接运行普通 Python 脚本并自动将其转换为 CLI 应用即使脚本内部完全没有使用 Typer。安装 Typer方式一使用 uv推荐先安装uv然后在项目中添加 Typer$ uv init awesome-project --bare $ cd awesome-project $ uv add typer --- 100%各命令的作用如下uv init创建新的 Python 项目awesome-project指定项目目录名--bare只生成最精简的pyproject.toml不生成示例文件方便后续手动创建应用代码。uv add typer在.venv中创建项目虚拟环境将 Typer 写入pyproject.toml并生成uv.lock锁定依赖版本保证其他机器可以复现相同环境。uv add会同时安装Typer 库和typer命令到项目的虚拟环境中。若要直接在 shell 中调用typer命令并启用补全需要先激活虚拟环境详见 安装指南$ source .venv/bin/activate # Linux、macOS $ .venv\Scripts\Activate.ps1 # Windows PowerShell $ source .venv/Scripts/activate # Windows Bash然后为当前 Shell 安装补全$ typer --install-completion重启终端后补全配置生效。每个新终端会话如要直接使用typer命令都需要再次激活虚拟环境。方式二使用 pip如果你习惯手动管理虚拟环境也可以创建并激活虚拟环境后执行pip install typer。两种方式都会同时安装 Typer 库与typer命令。说明Typer 的完整安装与虚拟环境激活流程可参阅仓库内的 安装指南。绝对最小示例用typer命令运行普通脚本Typer 最惊艳的用法之一是改造一个完全没用 Typer 的普通脚本。创建一个main.pydef main(name: str): print(fHello {name})这个脚本内部没有任何 Typer 代码但可以用typer命令把它当作 CLI 应用运行// 运行你的应用 $ typer main.py run // 缺少 name 参数时你会得到一个友好的错误提示 Usage: typer [PATH_OR_MODULE] run [OPTIONS] {name} Try typer [PATH_OR_MODULE] run --help for help. ╭─ Error ───────────────────────────────────────────╮ │ Missing argument name. │ ╰───────────────────────────────────────────────────╯ // 免费获得 --help $ typer main.py run --help Usage: typer [PATH_OR_MODULE] run [OPTIONS] {name} Run the provided Typer app. ╭─ Arguments ───────────────────────────────────────╮ │ * name str [required] │ ╰───────────────────────────────────────────────────╯ ╭─ Options ─────────────────────────────────────────╮ │ --help Show this message and exit. │ ╰───────────────────────────────────────────────────╯ // 传入 name 参数 $ typer main.py run Camila Hello Camila即使脚本内部未使用 Typertyper命令也能把其中的函数转换为完整的 CLI 应用这对简单的脚本场景已经非常实用。typer命令的底层工作机制从 typer/cli.py 的源码可以看到这个能力由typer.cli模块实现它定义了默认查找顺序默认应用名(app, cli, main)、默认函数名(main, cli, app)在运行时动态导入指定路径或模块typer main.py run中的main.py再在其中寻找 Typer 应用或函数。run子命令是在运行时动态挂载的maybe_add_run_to_cli()会检查目标模块找到可用的 Typer 对象后将其包装为名为run的子命令。你还可以通过--app指定模块中具体的 Typer 对象、用--func指定要转换的函数或用--version查看版本。命令还内置了utils docs子命令可自动生成 Markdown 格式的 CLI 文档甚至直接输出到 README.md 文件。注意typer命令支持自动补全当你创建 Python 包并用--install-completion安装补全或直接使用typer命令时补全即可生效。在代码中使用 Typertyper.run()现在让脚本真正使用 Typer。更新main.pyimport typer def main(name: str): print(fHello {name}) if __name__ __main__: typer.run(main)之后就可以直接用 Python 运行它// 运行你的应用 $ uv run python main.py // 缺少 name 参数时的友好错误 Usage: main.py [OPTIONS] {name} Try main.py --help for help. ╭─ Error ───────────────────────────────────────────╮ │ Missing argument name. │ ╰───────────────────────────────────────────────────╯ // 免费获得 --help $ uv run python main.py --help Usage: main.py [OPTIONS] {name} ╭─ Arguments ───────────────────────────────────────╮ │ * name str [required] │ ╰───────────────────────────────────────────────────╯ ╭─ Options ─────────────────────────────────────────╮ │ --help Show this message and exit. │ ╰───────────────────────────────────────────────────╯ // 传入 name 参数 $ uv run python main.py Camila Hello Camilatyper.run(main)是 Typer 提供的最简入口它隐式创建一个 Typer 应用把main函数包装为 CLI 命令。同样的脚本也可以继续用typer命令运行但并非必需。源码层面的印证在 typer/main.py 中run函数的核心逻辑是读取函数的参数签名get_params_from_function把每个参数按规则转换成 CLI 参数或选项。get_command_name()则定义了命令命名规则def get_command_name(name: str) - str: return name.lower().replace(_, -)即函数名say_hello会自动变成 CLI 命令名say-hello下划线转连字符、统一小写无需手动指定。升级示例构建包含两个子命令的应用接下来看一个稍复杂的示例——创建typer.Typer()应用并用app.command()注册两个子命令import typer app typer.Typer() app.command() def hello(name: str): print(fHello {name}) app.command() def goodbye(name: str, formal: bool False): if formal: print(fGoodbye Ms. {name}. Have a good day.) else: print(fBye {name}!) if __name__ __main__: app()这段代码做了三件事显式创建typer.Typer应用之前typer.run是隐式创建了一个用app.command()添加两个子命令直接调用app()像调用函数一样执行而不是用typer.run。查看新的帮助信息$ uv run python main.py --help Usage: main.py [OPTIONS] COMMAND [ARGS]... ╭─ Options ─────────────────────────────────────────╮ │ --install-completion Install completion │ │ for the current │ │ shell. │ │ --show-completion Show completion for │ │ the current shell, │ │ to copy it or │ │ customize the │ │ installation. │ │ --help Show this message │ │ and exit. │ ╰───────────────────────────────────────────────────╯ ╭─ Commands ────────────────────────────────────────╮ │ hello │ │ goodbye │ ╰───────────────────────────────────────────────────╯创建 Python 包后用--install-completion安装补全就能免费获得自动补全。现在你有两个子命令hello和goodbye。查看hello子命令的帮助$ uv run python main.py hello --help Usage: main.py hello [OPTIONS] {name} ╭─ Arguments ───────────────────────────────────────╮ │ * name str [required] │ ╰───────────────────────────────────────────────────╯ ╭─ Options ─────────────────────────────────────────╮ │ --help Show this message and exit. │ ╰───────────────────────────────────────────────────╯查看goodbye子命令的帮助$ uv run python main.py goodbye --help Usage: main.py goodbye [OPTIONS] {name} ╭─ Arguments ───────────────────────────────────────╮ │ * name str [required] │ ╰───────────────────────────────────────────────────╯ ╭─ Options ─────────────────────────────────────────╮ │ --formal --no-formal [default: no-formal] │ │ --help Show this message │ │ and exit. │ ╰───────────────────────────────────────────────────╯注意formal: bool False这个声明Typer 自动为布尔参数生成了--formal与--no-formal一对开关并默认使用no-formal。实际运行新应用// 使用 hello 命令 $ uv run python main.py hello Camila Hello Camila // 使用 goodbye 命令 $ uv run python main.py goodbye Camila Bye Camila! // 加上 --formal $ uv run python main.py goodbye --formal Camila Goodbye Ms. Camila. Have a good day.单命令与多命令的行为差异README 特别指出如果应用只有一个命令默认会在使用中省略命令名如python main.py Camila当有多个命令时必须显式包含命令名如python main.py hello Camila。从源码 typer/main.py 的get_command()可以印证这一行为当应用只有一个已注册命令且没有回调、没有子组时Typer 会生成一个单一 Command命令名被省略而当有多个命令、回调或子组时则生成一个 Group命令树。更详细的行为说明见 One or Multiple Commands。声明一次处处生效类型提示驱动一切Typer 的核心使用模式是把 CLI 参数arguments和 CLI 选项options的类型一次性声明为函数参数使用的都是标准的现代 Python 类型无需学习新语法或特定库的类与方法。例如int类型total: int或bool开关force: bool同样地文件、路径、枚举选项等类型都可以直接声明还有工具可以创建子命令组、添加元数据、进行额外的校验等。你获得的是极佳的编辑器支持包括随处补全和类型检查。你的用户获得的是自动的--help以及在安装你的包或使用typer命令时终端中的自动补全支持 Bash、Zsh、Fish、PowerShell。类型转换的源码实现类型提示并非只用于生成帮助信息它直接决定了参数如何被解析与校验。在 typer/main.py 的determine_type_convertor()中可以看到当类型是Path时生成param_path_convertor把字符串转换为pathlib.Path对象当类型是Enum时生成generate_enum_convertor把用户输入映射到对应的枚举成员列表、元组等复合类型则由generate_list_convertor、generate_tuple_convertor逐元素转换。在 typer/params.py 中Option()还提供了极为丰富的参数能力例如envvar从环境变量读取值prompt/confirmation_prompt/hide_input交互式提示与密码输入min/max/clamp数值范围校验越界时可自动钳制到边界值exists/file_okay/dir_okay/writable/readable/resolve_path路径的存在性、类型与权限校验formats自定义datetime的解析格式mode/encoding/atomic文件读写模式与原子写入count把选项变成计数器如-v、-vvautocompletion自定义补全函数parser/click_type接入自定义类型解析或 Click 类型。这些能力全部源自参数声明无需额外手写解析代码——这正是 README 中一次声明、多种能力的体现。深入依赖与实现细节运行时依赖Typer 的依赖非常精简见 pyproject.toml依赖版本要求用途rich13.8.0自动输出格式美观的错误信息如上述的╭─ Error ─╮样式框shellingham1.3.0安装补全时自动检测当前 Shellannotated-doc0.0.2从 Python 类型注解生成文档colorama仅 Windows 平台在 Windows 终端输出彩色文本同时Typer 要求Python 3.10。关于 Click已被内嵌vendoredTyper 早期依赖 ClickPython 社区流行的 CLI 构建库。从版本 0.26.0 起Typer 已将 Click 的源码内嵌vendored进自身即仓库中的 typer/_click 目录不再作为第三方包安装并统一了 Typer 与内嵌 Click 的代码交互便于未来维护。README 同时提示随着 Typer 代码库的持续改进部分 Click 功能未来将不再可用。typer-slim的历史与TYPER_USE_RICH过去存在一个精简版发行包typer-slim不包含rich、shellingham依赖也没有typer命令。但从 0.22.0 版本起已停止维护typer-slim现在只是完整安装 Typer。如果想全局禁用 Rich可以设置环境变量TYPER_USE_RICH为False或0。这一点在 typer/core.py 中有明确实现HAS_RICH parse_boolean_env_var(os.getenv(TYPER_USE_RICH), defaultTrue)它同时决定了默认的rich_markup_modeRich 可用时为rich否则为None。美观的异常处理在 typer/main.py 中Typer.__call__()会注册自定义的except_hook当用户代码抛出异常时若启用了 Rich就用 Rich 渲染出带上下文的漂亮堆栈可配置pretty_exceptions_enable、pretty_exceptions_show_locals、pretty_exceptions_short控制是否显示局部变量与完整堆栈未安装 Rich 时则过滤掉 Typer/Click 内部帧让开发者聚焦于自己的代码。README 中展示的╭─ Error ─╮错误框正是这一机制的直观体现。从入门到实战进一步探索本指南覆盖了 README 的核心路径。接下来可以顺着仓库内的教程继续深入初识 Typer从 Hello World 起步Typer 应用typer.Typer应用对象的完整配置命令Commands子命令、回调、上下文参数类型bool、int、datetime、enum、file、path、uuid 等参数自动补全为选项与参数自定义补全。仓库中的示例代码全部位于 docs_src 目录如最小示例 docs_src/first_steps/tutorial001_py310.py对应的自动化测试位于 tests其中 tests/test_cli 专门验证typer命令的各种行为tests/test_tutorial 逐篇验证教程示例它们是学习 Typer 行为最可信的参考。总结Typer 的核心理念可以浓缩为一句话用标准 Python 类型提示声明函数参数其余交给框架。从零代码改造普通脚本的typer命令到typer.run()的单命令应用再到typer.Typer()app.command()的多子命令应用Typer 保持了从简到繁的平滑演进自动帮助、自动补全、类型转换、友好错误提示均由声明自动生成。依赖精简rich、shellingham、annotated-doc以及仅 Windows 使用的 coloramaClick 自 0.26.0 起被内嵌维护typer-slim自 0.22.0 起停止支持——这些现状都可以在当前仓库的源码与配置中得到直接印证。如果你正在寻找一种声明式、类型安全、对用户友好的 Python CLI 方案Typer 是一个值得深入使用的选择。【免费下载链接】typerTyper, build great CLIs. Easy to code. Based on Python type hints.项目地址: https://gitcode.com/GitHub_Trending/ty/typer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表