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

posted @ 2026-02-05 10:24  Nolca  阅读(0)  评论(0)    收藏  举报