Python中如何正确使用(*args, **kwargs)进行参数传递?
class tracer(object):
def __init__(self, func):
self.calls = 0
self.func = func
def __call__(self, *args, **kwargs):
self.calls += 1
print('call %s to %s' % (self.calls, self.func.__name__))
return self.func(*args, **kwargs)
def __get__(self, instance, owner):
def wrapper(*args, **kwargs):
print('wrapper:args=%s ,kwargs=%s'% (args,kwargs))
return self(instance, *args, **kwargs)
return wrapper
class Person:
def __init__(self, name, pay):
self.name = name
self.pay = pay
@tracer
def giveRaise(self, percent):
self.pay *= (1.0+percent)
print("pay=",self.pay)
bob = Person('Bob Smith', 50000)
bob.giveRaise(.10)
上面代码的输出如下:
wrapper:args=(0.1,) ,kwargs={}
call 1 to giveRaise
pay= 55000.00000000001
我的问题是:wrapper 方法是在__get__方法内定义的,但是__get__方法并没有接收参数(*args, **kwargs),为何 wrapper 方法的(*args, **kwargs)参数会有值呢?
Python中如何正确使用(*args, **kwargs)进行参数传递?
2 回复
在Python里,*args和**kwargs是用来处理可变数量参数的两个核心工具,搞懂它们能让你的函数灵活不少。
简单说,*args用来收一堆没名字的位置参数,函数里拿到的是一个元组(tuple)。**kwargs则是收一堆有名字的关键字参数,拿到的是一个字典(dict)。名字不一定要叫args和kwargs,但星号*和双星号**是关键。
看个例子就明白了:
def example_func(required_arg, *args, **kwargs):
print(f"固定参数: {required_arg}")
print(f"*args 元组: {args}")
print(f"**kwargs 字典: {kwargs}")
# 调用
example_func("hello", 1, 2, 3, name="Alice", age=30)
输出会是:
固定参数: hello
*args 元组: (1, 2, 3)
**kwargs 字典: {'name': 'Alice', 'age': 30}
更实用的场景是写包装函数或者装饰器。比如你想写个函数,把参数原封不动传给另一个函数:
def wrapper(*args, **kwargs):
# 这里可以加一些自己的逻辑
print("准备调用目标函数...")
# 把收到的所有参数透传给另一个函数
target_function(*args, **kwargs)
def target_function(name, value=0):
print(f"目标函数执行: name={name}, value={value}")
# 调用包装器,参数会自动传递
wrapper("test", value=100)
关键点:
- 定义函数时,
*args必须在**kwargs之前。 - 调用函数时,
*iterable可以把可迭代对象展开成位置参数,**dict可以把字典展开成关键字参数。 - 这俩经常在继承、装饰器和需要通用接口的地方用。
总结:用*args收任意位置参数,用**kwargs收任意关键字参数,能让函数接口更通用。
相当于后面函数的装饰器了,你的 giveRaise 函数已经被 wrapper 替代了

