Python中 *args 和 **kwagrs 的区别

本文讲述了在Python中使用类型提示时,如何正确处理可变参数*args和**kwargs。作者指出,虽然尝试为它们指定完整类型会有误报,但实际应仅注解参数内容,如*args:str,**kwargs:int。PEP484规定了这种行为。
摘要由CSDN通过智能技术生成

当我开始写类型提示时,我对Python的可变参数运算符***(通常称为*args**kwargs)的使用也感到有些困惑。以下是我总结出的内容。

回想一下,*运算符用于捕获可变的位置参数并将其放入一个元组中,而**则用于捕获可变的关键字参数并将其放入一个字典中。例如,考虑以下函数:

def variable(*args, **kwargs):
    ...

在函数体内,args将是一个元组,而kwargs将是一个带有字符串键的字典。

在添加类型提示时,似乎自然而然地尝试声明argskwargs的完整类型。如果我们希望所有的值都是int,我们可能会尝试:

def variable(*args: tuple[int, ...], **kwargs: dict[str, int]) -> None:
    ...

(元组定义中的...表示可以是任意长度的元组。)

但这是不正确的。我们可以通过添加一个调用来检查:

variable(1, 2, 3, a=4, b=5, c=6)

在文件上运行Mypy时,它会发现每个参数都有问题:

$ mypy example.py
example.py:5: error: Argument 1 to "variable" has incompatible type "int"; expected "Tuple[int, ...]"
example.py:5: error: Argument 2 to "variable" has incompatible type "int"; expected "Tuple[int, ...]"
example.py:5: error: Argument 3 to "variable" has incompatible type "int"; expected "Tuple[int, ...]"
example.py:5: error: Argument "a" to "variable" has incompatible type "int"; expected "Dict[str, int]"
example.py:5: error: Argument "b" to "variable" has incompatible type "int"; expected "Dict[str, int]"
example.py:5: error: Argument "c" to "variable" has incompatible type "int"; expected "Dict[str, int]"
Found 6 errors in 1 file (checked 1 source file)

那正确的方式是什么呢?

  • 单个*始终绑定到一个元组,而**始终绑定到一个带有字符串键的字典。由于这个限制,类型提示只需要您定义所包含参数的类型。类型检查器会自动添加tuple[_, ...]dict[str, _]这些容器类型。

引入类型提示的Python增强提案(PEP 484)指定了这个规则:

任意参数列表也可以进行类型注释,因此以下定义是可以接受的:

def foo(*args: str, **kwds: int): ...

在函数foo的主体内,变量args的类型被推断为Tuple[str, ...],而变量kwds的类型为Dict[str, int]

因此,我们可以将我们的函数正确地类型提示为:

def variable(*args: str, **kwargs: int) -> None:
    ...

这样就可以通过类型检查了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值