python下函数参中的*args和**kwargs

214 阅读3分钟

说明

多个实参,放到一个元组里面,以*开头,可以传多个参数

**是形参中按照关键字传值把多余的传值以字典的方式呈现

*args:(表示的就是将实参中按照位置传值,多出来的值都给args,且以元组的方式呈现)

示例

def foo(x, *args):
    print(x)  # 1
    print(args)  # (2, 3, 4, 5)


foo(1, 2, 3, 4, 5)  # 其中的2,3,4,5都给了args

当args与位置参数和默认参数混用的情况下:(注意三者的顺序)

def foo(x, y=1, *args):
    print(x)  # 1
    print(y)  # 2
    print(args)  # (3, 4, 5)


foo(1, 2, 3, 4, 5)  # 其中的x为1,y=1的值被2重置了,3,4,5都给了args

(三者顺序是:位置参数、*args、默认参数)

def foo(x, *args, y=1):
    print(x)  # 1
    print(args)  # (2, 3, 4, 5)
    print(y)  # 1


foo(1, 2, 3, 4, 5)  # 其中的x为1,2,3,4,5都给了args,y按照默认参数依旧为1

其中关于*,可以从2个角度来看(需要拆分来看): 1、从形参的角度来看:

def foo(*args):  # 其实这一操作相当于def foo(a,b,c,d,e):
    print(args)  # (1, 2, 3, 4, 5)


foo(1, 2, 3, 4, 5)  # 其中的1,2,3,4,5都按照位置传值分别传给了a,b,c,d,e

2、从实参的角度来看:

def foo(x, y, z):
    print(x)  # 1
    print(y)  # 2
    print(z)  # 3


foo(*(1, 2, 3))  # 其中的*(1,2,3)拆开来看就是:foo(1,2,3),都按照位置传值分别传给了x,y,z

**kwargs:(表示的就是形参中按照关键字传值把多余的传值以字典的方式呈现)

def foo(x, **kwargs):
    print(x)  # 1
    print(kwargs)  # {'y': 1, 'a': 2, 'b': 3, 'c': 4}


foo(1, y=1, a=2, b=3, c=4)  # 将y=1,a=2,b=3,c=4以字典的方式给了kwargs

关于**kwargs与位置参数、*args、默认参数混着用的问题:(注意顺序)

位置参数、*args、**kwargs三者的顺序必须是位置参数、*args、**kwargs,不然就会报错:

def foo(x, *args, **kwargs):
    print(x)  # 1
    print(args)  # (2, 3, 4)
    print(kwargs)  # {'y': 1, 'a': 2, 'b': 3, 'c': 4}


foo(1, 2, 3, 4, y=1, a=2, b=3,
    c=4)  # 将1传给了x,将2,3,4以元组方式传给了args,y=1,a=2,b=3,c=4以字典的方式给了kwargs
    

def foo(x,**kwargs,*args):
    print(x)
    print(args)
    print(kwargs)
foo(1,y=1,a=2,b=3,c=4,2,3,4)

# 报错: SyntaxError: invalid syntax

位置参数、默认参数、**kwargs三者的顺序必须是位置参数、默认参数、**kwargs,不然就会报错:

def foo(x, y=1, **kwargs):
    print(x)  # 1
    print(y)  # 1
    print(kwargs)  # {'a': 2, 'b': 3, 'c': 4}


foo(1, a=2, b=3, c=4)  # 将1按照位置传值给x,y按照默认参数为1,a=2,b=3,c=4以字典的方式给了kwargs

其中关于**,可以从2个角度来看(需要拆分来看): 1、从形参的角度来看:

def foo(**kwargs):  # 其实就是相当于def foo(y,a,b,c)
    print(kwargs)   # {'y': 1, 'a': 2, 'b': 3, 'c': 4}


foo(y=1, a=2, b=3, c=4)

2、从实参的角度来看:

def foo(a, b, c, d):
    print(a)  # 2
    print(b)  # 3
    print(c)  # 4
    print(d)  # 5


foo(**{
    "a": 2,
    "b": 3,
    "c": 4,
    "d": 5
})  # **{"a":2,"b":3,"c":4,"d":5}是将字典里的每个值按照关键字传值的方式传给a,b,c,d

其他

import json


def safe_loads_json(json_str, **kwargs):
    try:
        return json.loads(json_str)
    except Exception as e:
        # print(e)
        if kwargs.get('default') is not None:
            return kwargs.get('default')
        else:
            return {}


print(safe_loads_json(
    '{"a": 2, "b": 3, "c": 4, "d": 5}'))  # {'a': 2, 'b': 3, 'c': 4, 'd': 5}
print(safe_loads_json(''))  # {}
print(safe_loads_json('', default=[]))  # []

参考

python函数——形参中的:*args和**kwargs