Python中*args和**kwargs的使用

Python中*args和**kwargs的使用

技术背景

在Python编程中,有时我们需要定义一个能接受任意数量参数的函数。*args**kwargs 就是Python提供的两个强大特性,用于处理这种情况。*args 用于接收任意数量的位置参数,它会将这些参数封装成一个元组;**kwargs 用于接收任意数量的关键字参数,它会将这些参数封装成一个字典。

实现步骤

1. 使用 *args

当不确定函数会接收多少个位置参数时,可以使用 *args。示例代码如下:

1
2
3
4
5
def print_everything(*args):
for count, thing in enumerate(args):
print('{0}. {1}'.format(count, thing))

print_everything('apple', 'banana', 'cabbage')

在上述代码中,*args 接收了三个位置参数,并将它们封装成一个元组。然后通过 enumerate 函数遍历这个元组并打印每个元素。

2. 使用 **kwargs

当需要处理未预先定义的关键字参数时,可以使用 **kwargs。示例代码如下:

1
2
3
4
5
def table_things(**kwargs):
for name, value in kwargs.items():
print('{0} = {1}'.format(name, value))

table_things(apple='fruit', cabbage='vegetable')

在这个例子中,**kwargs 接收了两个关键字参数,并将它们封装成一个字典。然后通过 items 方法遍历这个字典并打印每个键值对。

3. 结合使用 *args 和 **kwargs

可以在同一个函数定义中同时使用 *args**kwargs,但 *args 必须在 **kwargs 之前。示例代码如下:

1
2
3
4
5
6
7
8
def func(required_arg, *args, **kwargs):
print(required_arg)
if args:
print(args)
if kwargs:
print(kwargs)

func("required argument", 1, 2, '3', keyword1=4, keyword2="foo")

在这个函数中,required_arg 是一个必需的位置参数,*args 接收额外的位置参数,**kwargs 接收额外的关键字参数。

4. 在函数调用中使用 * 和 **

*** 语法也可以在函数调用时使用,用于解包列表或字典。示例代码如下:

1
2
3
4
5
def print_three_things(a, b, c):
print('a = {0}, b = {1}, c = {2}'.format(a, b, c))

mylist = ['aardvark', 'baboon', 'cat']
print_three_things(*mylist)

在这个例子中,*mylist 将列表 mylist 解包成三个独立的参数,并传递给 print_three_things 函数。

核心代码

以下是几个使用 *args**kwargs 的完整示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 使用 *args 计算任意数量数字的和
def sumFunction(*args):
result = 0
for x in args:
result += x
return result

print(sumFunction(3, 4, 6, 3, 6, 8, 9))

# 使用 **kwargs 处理任意关键字参数
def someFunction(**kwargs):
if 'text' in kwargs:
print(kwargs['text'])

someFunction(text="foo")

# 结合使用 *args 和 **kwargs 的装饰器示例
import functools

def mydecorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
print("Calling f", args, kwargs)
v = f(*args, **kwargs)
print("f returned", v)
return v
return wrapper

@mydecorator
def example_function(a, b):
return a + b

print(example_function(2, 3))

最佳实践

1. 子类化

在子类化时,使用 *args**kwargs 可以方便地扩展父类的行为,而无需了解父类的具体参数。示例代码如下:

1
2
3
4
5
6
7
8
9
10
class Foo(object):
def __init__(self, value1, value2):
print(value1, value2)

class MyFoo(Foo):
def __init__(self, *args, **kwargs):
print('myfoo')
super(MyFoo, self).__init__(*args, **kwargs)

my_foo = MyFoo(1, 2)

2. 包装函数

在编写包装函数(如装饰器)时,使用 *args**kwargs 可以接受任意参数并传递给被包装的函数。示例代码如下:

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

def mydecorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
print("Calling f", args, kwargs)
v = f(*args, **kwargs)
print("f returned", v)
return v
return wrapper

@mydecorator
def example_function(a, b):
return a + b

print(example_function(2, 3))

常见问题

1. 能否在函数调用的中间扩展列表作为位置参数?

在Python 2中,无法在函数调用的中间扩展列表作为位置参数。但在Python 3中,这种操作是可行的。

2. *args**kwargs 必须使用这两个名称吗?

不是的,*** 是语法,argskwargs 只是约定俗成的名称,你可以使用其他名称,但为了代码的可读性,建议使用这两个名称。

3. 在Python 2中,能否使用 *args 扩展与 print 语句一起使用?

在Python 2中,print 是语句而不是函数,因此不能使用 *args 扩展与 print 语句一起使用。但可以通过 from __future__ import print_function 来将 print 作为函数使用,或者手动遍历 args 并打印每个元素。在Python 3中,print 是函数,可以直接使用 *args 扩展。


Python中*args和**kwargs的使用
https://119291.xyz/posts/2025-04-21.python-args-kwargs-usage/
作者
ww
发布于
2025年4月21日
许可协议