Python函数可变参数的使用
Python函数可变参数指的是不确定参数个数的情况下,如何在函数中使用这些参数。在Python中,有两种方式实现可变参数:参数前加 * 或 **。
参数前加 * 表示参数被打包成一个元组(tuple),而参数前加 ** 则表示参数被打包成一个字典(dictionary)。
下面分别介绍这两种方式的具体用法。
一、参数前加 *
如果我们在定义函数的时候,将参数前加上 *,那么函数就可以接收不定数目的非关键字参数,在函数内部这些参数都会被打包成一个元组。
示例代码:
def myfunc(*args):
for arg in args:
print(arg)
myfunc(1, 2, 3)
myfunc('hello', 'world')
输出:
1 2 3 hello world
上述代码中,myfunc函数可以接收任意数目的参数,将这些参数打包成一个元组args,然后使用for循环遍历打印出来。
二、参数前加 **
如果我们在定义函数的时候,将参数前加上 **,那么函数就可以接收不定数目的关键字参数,在函数内部这些参数都会被打包成一个字典。
示例代码:
def myfunc(**kwargs):
for key, value in kwargs.items():
print(key, ':', value)
myfunc(name='Tom', age=20, gender='male')
myfunc(city='Beijing', country='China')
输出:
name : Tom age : 20 gender : male city : Beijing country : China
上述代码中,myfunc函数可以接收任意数目的关键字参数,将这些参数打包成一个字典kwargs,然后使用for循环遍历打印出来。
三、同时使用 * 和 **
除了分别使用 * 和 ** 外,还可以同时使用这两个操作符。在这种情况下,我们必须先使用 * 来接收所有的非关键字参数,然后使用 ** 来接收所有的关键字参数。
示例代码:
def myfunc(*args, **kwargs):
for arg in args:
print(arg)
for key, value in kwargs.items():
print(key, ':', value)
myfunc(1, 2, 3, name='Tom', age=20, gender='male')
myfunc('hello', 'world', city='Beijing', country='China')
输出:
1 2 3 name : Tom age : 20 gender : male hello world city : Beijing country : China
上述代码中,myfunc函数可以接收任意数目的非关键字参数和关键字参数,将这些参数打包成一个元组args和一个字典kwargs,然后使用for循环遍历打印出来。
四、参数的顺序问题
在定义函数时,我们必须先定义接收所有非关键字参数的参数(即 *args),然后定义接收所有关键字参数的参数(即 **kwargs)。否则程序会报错。
示例代码:
# 函数定义顺序错误,会报错
def myfunc(**kwargs, *args):
pass
输出:
SyntaxError: invalid syntax
需要注意的是,在调用函数时,我们可以先传递关键字参数,再传递非关键字参数,也可以反过来。但是如果传递非关键字参数时,必须按照函数定义时的顺序传递。
示例代码:
def myfunc(a, b, *args, **kwargs):
print(a, b)
for arg in args:
print(arg)
for key, value in kwargs.items():
print(key, ':', value)
myfunc(1, 2, 'x', 'y', name='Tom', age=20, gender='male')
myfunc(1, 2, name='Tom', age=20, gender='male', 'x', 'y')
输出:
1 2 x y name : Tom age : 20 gender : male 1 2 SyntaxError: positional argument follows keyword argument
上述代码中, 次调用myfunc函数时,先传递了两个非关键字参数,然后再传递了剩下的关键字参数和非关键字参数。第二次调用myfunc函数时,先传递了两个非关键字参数,然后又传递了剩下的关键字参数和非关键字参数,但是这时会报错,因为传递了不符合顺序的参数。
总结:
Python函数可变参数用于在不确定参数个数的情况下,将这些参数打包并传入函数中使用。可以使用 * 来接收所有的非关键字参数,使用 ** 来接收所有的关键字参数,或者同时使用 * 和 ** 来接收所有的参数。在传递参数时,必须先传递所有的关键字参数,再传递所有的非关键字参数。
