Python:为什么在函数中使用重载而不是*args(特别是当参数类型不影响函数的运行方式时)
编辑: 我正在查看内置Python:为什么在函数中使用重载而不是*args(特别是当参数类型不影响函数的运行方式时),python,loops,itertools,typechecking,Python,Loops,Itertools,Typechecking,编辑: 我正在查看内置zip()函数的类型注释 我知道重载(在类型检查的上下文中)可以根据给定的参数类型修改函数的行为 @overload def zip(__iter1: Iterable[_T1]) -> List[Tuple[_T1]]: ... @overload def zip(__iter1: Iterable[_T1], __iter2: Iterable[_T2]) -> List[Tuple[_T1, _T2]
zip()
函数的类型注释
我知道重载(在类型检查的上下文中)可以根据给定的参数类型修改函数的行为
@overload
def zip(__iter1: Iterable[_T1]) -> List[Tuple[_T1]]: ...
@overload
def zip(__iter1: Iterable[_T1],
__iter2: Iterable[_T2]) -> List[Tuple[_T1, _T2]]: ...
@overload
def zip(__iter1: Iterable[_T1], __iter2: Iterable[_T2],
__iter3: Iterable[_T3]) -> List[Tuple[_T1, _T2, _T3]]: ...
@overload
def zip(__iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3],
__iter4: Iterable[_T4]) -> List[Tuple[_T1, _T2, _T3, _T4]]: ...
@overload
def zip(__iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3],
__iter4: Iterable[_T4], __iter5: Iterable[_T5]) -> List[Tuple[_T1, _T2, _T3, _T4, _T5]]: ...
@overload
def zip(__iter1: Iterable[Any], __iter2: Iterable[Any], __iter3: Iterable[Any],
__iter4: Iterable[Any], __iter5: Iterable[Any], __iter6: Iterable[Any],
*iterables: Iterable[Any]) -> List[Tuple[Any, ...]]: ...
这是一个优化。可以处理任意数量参数的版本需要使用额外级别的循环。固定数量参数的版本可以硬编码访问每个参数,这更有效
zip()
的绝大多数用法只有2-3个参数,因此,尽管这种优化可能很小,但总的来说是非常有益的。重载装饰器用于静态类型分析,而不是实现。事实上,问题中显示的代码只是类型注释-zip
是内置的,它不是用Python实现的
各种重载的目的是保留参数的数量和类型。例如,它声明一个zip
超过三个iterable会生成三个元素与iterable元素类型匹配的元组。变量*args
和Any
的最终重载仅是未指定情况下的一个总括
@overload
def zip(__iter1: Iterable[Any], __iter2: Iterable[Any], __iter3: Iterable[Any],
__iter4: Iterable[Any], __iter5: Iterable[Any], __iter6: Iterable[Any],
*iterables: Iterable[Any]) -> List[Tuple[Any, ...]]: ...