python 为什么我觉得*args会破坏api接口设计的稳定性
前置知识
python中,我们可以用解包写法,定义一个函数的入参:
def myFunc(*args: int, **kwargs: bool): ...
type(args) # tuple[int]
type(kwargs) # dict[str, bool]
pythony有个定义或限制,位置参数position arg必须在关键字参数keyword arg的前面:
def myFunc(posArg, /, arg, *, kwarg ): ...
# /的左边必须是位置参数
# *的右边必须是关键字参数
# 合法调用:
myFunc('pos', arg='both', kwarg='kw only')
myFunc('pos', 'both', kwarg='kw only')
自然也会要求*args必须在**kwargs的前面,如开头所示。
*args一般不应用于定义入参
*args会破坏api设计的稳定性:
def myFunc(*args: int, kw1: int): ...
myFunc(1,kw1=2) # 正确✔
myFunc(1,2) # 错误❌
def myFunc(args: tuple[int], kw1: int): ...
myFunc((1,),kw1=2) # 正确✔
myFunc((1,),2) # 正确✔
条条大路通罗马,不过我喜欢不用*args来定义入参
*args用途
透明传参
yourFunc(*args, **kwargs)
装饰器
import functools
def log_calls(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
# 打印调用信息
args_repr = [repr(a) for a in args]
kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()]
signature = ", ".join(args_repr + kwargs_repr)
print(f"Calling {func.__name__}({signature})")
# 调用原函数
result = func(*args, **kwargs)
# 打印返回值
print(f"{func.__name__} returned {result!r}")
return result
return wrapper
补充阅读:静态类型提示/自动补全kwargs

浙公网安备 33010602011771号