You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Typer中实现参数继承/分组?是否支持类似argparse的互斥组?

在Typer中复用共享参数及实现互斥组功能

一、复用多个命令的共享参数

针对非子命令的多个命令共享参数的场景,有三种实用方式避免重复编写:

1. 定义共享参数变量

把重复的参数(如数据库连接参数)提前定义为typer.Option或typer.Argument实例,在每个命令函数中直接引用:

import typer

# 定义共享的数据库参数
db_host = typer.Option("localhost", help="数据库主机地址")
db_port = typer.Option(5432, help="数据库端口")
db_user = typer.Option("admin", help="数据库用户名")

app = typer.Typer()

@app.command()
def export_data(
    host: str = db_host,
    port: int = db_port,
    user: str = db_user,
    output_path: str = typer.Argument(..., help="导出文件路径")
):
    typer.echo(f"从{host}:{port}导出数据到{output_path}")

@app.command()
def import_data(
    host: str = db_host,
    port: int = db_port,
    user: str = db_user,
    input_path: str = typer.Argument(..., help="导入文件路径")
):
    typer.echo(f"从{input_path}导入数据到{host}:{port}")

if __name__ == "__main__":
    app()

2. 装饰器封装共享参数

如果参数较多,可自定义装饰器将共享参数注入命令函数:

import typer
from functools import wraps

def with_db_params(func):
    @wraps(func)
    def wrapper(
        host: str = typer.Option("localhost", help="数据库主机地址"),
        port: int = typer.Option(5432, help="数据库端口"),
        user: str = typer.Option("admin", help="数据库用户名"),
        *args, **kwargs
    ):
        return func(host, port, user, *args, **kwargs)
    return wrapper

app = typer.Typer()

@app.command()
@with_db_params
def export_data(host: str, port: int, user: str, output_path: str):
    typer.echo(f"从{host}:{port}导出数据到{output_path}")

@app.command()
@with_db_params
def import_data(host: str, port: int, user: str, input_path: str):
    typer.echo(f"从{input_path}导入数据到{host}:{port}")

if __name__ == "__main__":
    app()

3. 依赖注入(Typer 0.3+支持)

通过Typer的依赖注入功能,定义获取共享参数的函数,在命令中用typer.Depends引用:

import typer
from typing import Tuple

def get_db_params(
    host: str = typer.Option("localhost", help="数据库主机地址"),
    port: int = typer.Option(5432, help="数据库端口"),
    user: str = typer.Option("admin", help="数据库用户名")
) -> Tuple[str, int, str]:
    return host, port, user

app = typer.Typer()

@app.command()
def export_data(
    db_params: Tuple[str, int, str] = typer.Depends(get_db_params),
    output_path: str = typer.Argument(..., help="导出文件路径")
):
    host, port, user = db_params
    typer.echo(f"从{host}:{port}导出数据到{output_path}")

@app.command()
def import_data(
    db_params: Tuple[str, int, str] = typer.Depends(get_db_params),
    input_path: str = typer.Argument(..., help="导入文件路径")
):
    host, port, user = db_params
    typer.echo(f"从{input_path}导入数据到{host}:{port}")

if __name__ == "__main__":
    app()

二、实现类似argparse的互斥组功能

Typer基于Click构建,完全支持参数互斥组,常用两种实现方式:

1. 通过context_settings定义互斥组

注册命令时,通过context_settings配置互斥组规则:

import typer

app = typer.Typer()

@app.command(
    context_settings={"mutually_exclusive_groups": [
        {"name": "auth_mode", "options": ["token", "username"]}
    ]}
)
def login(
    token: str = typer.Option(None, help="认证令牌"),
    username: str = typer.Option(None, help="用户名"),
    password: str = typer.Option(None, help="密码")
):
    if token:
        typer.echo(f"使用令牌{token}登录")
    elif username and password:
        typer.echo(f"使用用户名{username}登录")
    else:
        typer.echo("请提供令牌或用户名+密码")

if __name__ == "__main__":
    app()

上述代码中,auth_mode组内的token和username参数互斥,无法同时传入。

2. 使用Click的MutuallyExclusiveOption

直接指定参数的cls为Click的MutuallyExclusiveOption,关联互斥参数:

import typer
from click import MutuallyExclusiveOption

app = typer.Typer()

@app.command()
def login(
    token: str = typer.Option(
        None, 
        help="认证令牌",
        cls=MutuallyExclusiveOption,
        mutually_exclusive=["username"]
    ),
    username: str = typer.Option(None, help="用户名"),
    password: str = typer.Option(None, help="密码")
):
    if token:
        typer.echo(f"使用令牌{token}登录")
    elif username and password:
        typer.echo(f"使用用户名{username}登录")
    else:
        typer.echo("请提供令牌或用户名+密码")

if __name__ == "__main__":
    app()

内容的提问来源于stack exchange,提问作者Tom Ron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:08:21