Python中*和**在参数中的作用详解

Python中*和**在参数中的作用详解

技术背景

在Python编程中,*** 操作符在函数参数处理方面具有特殊用途。它们允许函数接受任意数量的位置参数和关键字参数,这在处理不确定参数数量的情况时非常有用。同时,它们也可以用于函数调用时的参数解包操作。

实现步骤

1. 理解位置参数和关键字参数

  • 位置参数:函数定义时按顺序排列的参数,调用时需按顺序传入对应的值。
1
2
3
4
5
6
def test(a, b, c):
print(a)
print(b)
print(c)

test(1, 2, 3)
  • 关键字参数:函数调用时通过参数名指定参数值,不依赖参数顺序。
1
2
3
4
5
6
def test(a=0, b=0, c=0):
print(a)
print(b)
print(c)

test(a=1, b=2, c=3)

2. *** 在函数调用中的使用

  • * 操作符:用于将列表或元组解包为位置参数。
1
2
3
4
5
6
7
def sum(a, b):
print(a + b)

my_tuple = (1, 2)
my_list = [1, 2]
sum(*my_tuple)
sum(*my_list)
  • ** 操作符:用于将字典解包为关键字参数。
1
2
my_dict = {'a': 1, 'b': 2}
sum(**my_dict)

3. *** 在函数定义中的使用

  • *args:用于接受任意数量的位置参数,这些参数会被打包成一个元组。
1
2
3
4
5
6
7
def sum(*args):
total = 0
for a in args:
total += a
print(total)

sum(1, 2, 3, 4)
  • **kwargs:用于接受任意数量的关键字参数,这些参数会被打包成一个字典。
1
2
3
4
5
6
7
def sum(**args):
total = 0
for k, v in args.items():
total += v
print(total)

sum(a=1, b=2, c=3, d=4)

4. Python 3 中的新特性

  • 关键字仅参数:在 *args 之后的参数必须以关键字参数的形式传入。
1
2
3
4
def foo(arg, kwarg=None, *args, kwarg2=None, **kwargs):
return arg, kwarg, args, kwarg2, kwargs

print(foo(1, 2, 3, 4, 5, kwarg2='kwarg2', bar='bar', baz='baz'))
  • 仅允许关键字参数:使用单独的 * 表示后面的参数必须是关键字参数。
1
2
3
4
def foo(arg, kwarg=None, *, kwarg2=None, **kwargs):
return arg, kwarg, kwarg2, kwargs

print(foo(1, 2, kwarg2='kwarg2', foo='foo', bar='bar'))

核心代码

接受任意数量的位置和关键字参数

1
2
3
4
5
6
7
def foo(*args, **kwargs):
print(args)
print(kwargs)

a = (1, 2, 3)
b = {'aa': 11, 'bb': 22}
foo(*a, **b)

装饰器中使用 *args**kwargs

1
2
3
4
5
6
7
8
9
10
11
12
13
import functools

def decorator(function):
@functools.wraps(function)
def wrapper(*args, **kwargs):
preprocess()
function(*args, **kwargs)
postprocess()
return wrapper

@decorator
def foo(a, b, c, d=0, e=100):
differentiating_process_foo(a, b, c, d, e)

最佳实践

  • 使用标准命名:在使用 *** 接受可变参数时,建议使用 *args**kwargs 作为参数名,以遵循Python社区的约定。
  • 参数顺序:在函数定义中,参数顺序通常为:普通参数、*args、关键字仅参数、**kwargs
  • 代码复用:在编写装饰器或需要处理不同参数组合的函数时,使用 *args**kwargs 可以提高代码的复用性。

常见问题

  • ** 只能用于字典** 操作符专门用于解包字典,如果传入非字典对象会引发错误。
  • 参数重复问题:不能对非可选参数进行重复赋值,否则会引发错误。
  • ** 必须在 * 之后:在函数定义中,如果同时使用 *args**kwargs**kwargs 必须放在 *args 之后。

Python中*和**在参数中的作用详解
https://119291.xyz/posts/2025-05-09.python-asterisk-parameter-usage/
作者
ww
发布于
2025年5月9日
许可协议