Python 中的 *args 和 **kwargs

时间:2022-09-08 21:24:40

在阅读Python源码时, 经常会看到如下函数的定义:


def fun(*args, **kwargs):


很多同学可能会对此感到困惑,这个*args 和 **kwargs 是什么东西, 为啥会在源码中应用这么广泛呢?


这就要从函数的参数说起了。函数在传参时通常分为四种情况:


  • 普通参数,即在调用函数时必须按照准确的顺序来进行参数传递。

  • 默认参数,即参数含有默认值,在调用函数时可以进行参数传递,若没有进行参数传递则使用默认值,要注意,默认参数必须在普通参数的右侧(否则解释器无法解析)。

  • 元组参数,即 *args,参数格式化存储在一个元组中,长度没有限制,必须位于普通参数和默认参数之后

  • 字典参数,即 **kwargs,参数格式化存储在一个字典中,必须位于参数列表的最后面


普通参数实例如下,在调用函数的时候必须传入参数,否则会抛出 TypeError 异常:


def fun(name):
   print 'Hello', name

fun('Python')


默认参数必须跟在普通参数之后,不能在普通参数之前,默认参数可以传值,也可以不传,不传值时就采用默认参数:


def fun(base, rate=0.1):
   return base + base*rate

fun(100)
fun(100, 0.2)


元组参数需要跟在普通参数和默认参数的后面,其最大的特点就是不限制长度:


def fun(arg1, arg2='Default', *args):
   print 'arg1:', arg1
   print 'arg2:', arg2
   for eacharg in args:
       print 'tuple arg:', eacharg


fun('Python')
fun('Python', 'Excellent')
fun('Python', 'Excellent', 'I', 'Love', 'Python', 100, 'Years')


最后一次调用的结果为:

arg1: Python

arg2: Excellent

tuple arg: I

tuple arg: Love

tuple arg: Python

tuple arg: 100

tuple arg: Years


由此可见,元组的长度是不受限制的。


字典参数必须跟在其它参数后面,并且长度也是不受限制的:


def fun(arg1, arg2='Default', *args, **kwargs):
   print 'arg1:', arg1
   print 'arg2:', arg2
   for eacharg in args:
       print 'tuple arg:', eacharg

   for eachkwarg in kwargs.keys():
       print 'dict arg', eachkwarg, ':', kwargs[eachkwarg]

fun('Python', 'Excellent', 'I', 'Love', language='Python', number=100, time='Years')


运行的输出结果为:

arg1: Python

arg2: Excellent

tuple arg: I

tuple arg: Love

dict arg number : 100

dict arg language : Python

dict arg time : Years


当我们将普通参数和默认参数都放到元组或者字典参数时,函数的定义就变为仅仅剩余元组参数和字典参数了:


def fun(*args, **kwargs):
   for eacharg in args:
       print 'tuple arg:', eacharg

   for eachkwarg in kwargs.keys():
       print 'dict arg', eachkwarg, ':', kwargs[eachkwarg]

fun('Python', 'Excellent', 'I', 'Love', language='Python', number=100, time='Years')


这也是很多源码中对函数的定义。运行结果输出为:

tuple arg: Python

tuple arg: Excellent

tuple arg: I

tuple arg: Love

dict arg number : 100

dict arg language : Python

dict arg time : Years


所有参数均可以正确获取。


你理解了函数参数传递的四种形式了吗?下次遇到 *args 和 **kwargs 你还会感到疑惑吗?



Python 中的 *args 和 **kwargs