ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Typer 子应用(sub-Typer)的 callback 谁生效:add_typer 的 callback 优先级

Typer 子应用(sub-Typer)的 callback 谁生效:add_typer 的 callback 优先级 Typer 子应用sub-Typer的 callback 谁生效add_typer 的 callback 优先级【免费下载链接】typerTyper, build great CLIs. Easy to code. Based on Python type hints.项目地址: https://gitcode.com/GitHub_Trending/ty/typer当你用app.add_typer()把一个独立的typer.Typer()应用挂到主应用下面时这个子应用sub-Typer的 callback 有三个可能的定义位置typer.Typer(callback...)构造参数、sub_app.callback()装饰器以及app.add_typer(..., callback...)的callback参数。如果三个位置都定义了 callback运行时到底执行哪一个本文按 Typer 仓库 subcommands/callback-override 教程 的 4 个可运行示例逐段验证最后给出确定的优先级结论。callback 在子应用中的作用子应用的 callback 会在执行它自己的任何子命令时运行并且可以声明位于该子应用命令之前的CLI parameterscallback-override 教程 原文It can handle anyCLI parametersthat go before its own commands and execute any extra code。也就是说主应用里的users create Camila执行时users这个子应用的 callback 先执行然后才是create命令函数。这个先执行的特性正是本文判断哪个 callback 生效的验证依据跑一条命令看第一行输出是谁打印的。准备条件环境中已安装 Typer安装方式见 docs/tutorial/install.md。仓库文档中统一使用uv run python main.py ...的调用方式因此下面的代码都假定为独立文件main.py。4 个示例文件也已存在于仓库中可以直接在仓库内运行例如python docs_src/subcommands/callback_override/tutorial001_py310.py users create Camila第 1 步用 users_app.callback() 定义这是最直观的方式tutorial001 源码import typer app typer.Typer() users_app typer.Typer() app.add_typer(users_app, nameusers) users_app.callback() def users_callback(): print(Running a users command) users_app.command() def create(name: str): print(fCreating user: {name}) if __name__ __main__: app()运行并验证以下为文档示例输出$ uv run python main.py users create Camila // Notice the first message is not created by the command function but by the callback Running a users command Creating user: Camila第一行Running a users command由 callback 打印第二行由create命令打印。这个两行输出的结构在后续所有示例中保持不变第一行内容就是判断依据。第 2 步改用 typer.Typer(callback...) 构造参数callback 也可以不写装饰器而是在创建子应用时直接传入tutorial002 源码import typer app typer.Typer() def users_callback(): print(Running a users command) users_app typer.Typer(callbackusers_callback) app.add_typer(users_app, nameusers) users_app.command() def create(name: str): print(fCreating user: {name}) if __name__ __main__: app()文档明确说明这种方式与第 1 步完全等价只是 callback 的另一个放置位置。运行输出与第 1 步一致Running a users commandCreating user: Camila。第 3 步两种方式同时定义时谁赢现在故意在两个位置都定义 callback构造时用typer.Typer(callbackdefault_callback)之后又用users_app.callback()定义user_callback()tutorial003 源码import typer app typer.Typer() def default_callback(): print(Running a users command) users_app typer.Typer(callbackdefault_callback) app.add_typer(users_app, nameusers) users_app.callback() def user_callback(): print(Callback override, running users command) users_app.command() def create(name: str): print(fCreating user: {name}) if __name__ __main__: app()运行输出文档示例$ uv run python main.py users create Camila // Notice the message from the new callback Callback override, running users command Creating user: Camila第一行变成了Callback override, running users command说明app.callback()覆盖了typer.Typer(callbacksome_function)。文档原文As app.callback() takes precedence over typer.Typer(callbacksome_function), now our CLI app will use this new callback.。这条规则与 commands/callback 教程 中主应用的规则一致对 sub-Typer 同样适用。第 4 步add_typer(callback...) 是最高优先级最后把 callback 放在app.add_typer()的callback参数里tutorial004 源码。注意这个示例里三个位置的 callback 都存在构造时的default_callback、装饰器定义的user_callback而且它在add_typer调用之后才定义以及add_typer的callback_for_add_typerimport typer app typer.Typer() def default_callback(): print(Running a users command) users_app typer.Typer(callbackdefault_callback) def callback_for_add_typer(): print(I have the high land! Running users command) app.add_typer(users_app, nameusers, callbackcallback_for_add_typer) users_app.callback() def user_callback(): print(Callback override, running users command) users_app.command() def create(name: str): print(fCreating user: {name}) if __name__ __main__: app()运行输出文档示例$ uv run python users create Camila // Notice the message from the callback added in add_typer() I have the high land! Running users command Creating user: Camila第一行是add_typer(callback...)传入的callback_for_add_typer打印的。文档特别强调优先级归app.add_typer()且与代码书写顺序无关——示例中users_app.callback()定义在add_typer调用之后但仍然是add_typer传入的 callback 生效。结论完整的优先级顺序综合 4 个可运行示例sub-Typer 的 callback 优先级从高到低为优先级定义位置示例中的函数1最高app.add_typer(users_app, callback...)callback_for_add_typer2users_app.callback()user_callback3最低typer.Typer(callback...)default_callback验证方式统一为运行python main.py users create Camila看第一行输出。Creating user: Camila来自命令函数始终不变第一行变化说明生效的 callback 发生了变化。add_typer的callback参数在源码签名中的定义见 typer/main.pydocstring 为 Add a callback to this app。限制与边界callback 声明的 CLI 参数必须位于它管辖的命令名之前。commands/callback 教程 中展示了放错位置的报错示例main.py create --verbose Camila会得到Error: No such option: --verbose因为--verbose属于 callback 的选项必须写main.py --verbose create Camila。本文结论只覆盖 callback 的覆盖优先级子命令的name、help也有各自的优先级规则见 subcommands/name-and-help 教程。挂载子应用本身的操作name参数、--help中列出子应用见 subcommands/add-typer 教程。【免费下载链接】typerTyper, build great CLIs. Easy to code. Based on Python type hints.项目地址: https://gitcode.com/GitHub_Trending/ty/typer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表