赞
踩
目录
形参的英文名:parameters,简写pars;实参的英文名:arguments,简写args。
函数定义时,写在函数名后面括号里的变量名就是形参;函数调用时,写在函数名后面括号里的要传给形参的值(value)或者引用(对象地址)就是实参。
函数参数传递的本质就是:用实参给形参赋值的操作
- def add(a, b): # 这里的a,b就是形参,形式参数。
- return a + b
-
-
- re = add(1, 2) # 这里的1,2就是实参,实际参数,把1,2分别传递给形参a,b
- print(re) # 显示3
- def func(a, b, c): # a,b,c就是位置参数,以变量形式存在
- print(f'a={a},b={b},c={c}')
-
-
- func(1, 2, 3) # 1,2,3也称为位置参数,确切一点叫做位置实参
- # a=1,b=2,c=3
- '''
- 按照位置顺序给形参依次传值,而且位置形参和位置实参的个数要保持一致。如上面,有a,b,c三个位
- 置形参,就需要传1,2,3三个位置实参
- '''
ps:位置参数有位置形参和位置实参两种
- def func(a=1, b=2, c=3): # a,b,c就是默认参数
- print(f'a={a},b={b},c={c}')
-
-
- func()# 使用了默认参数可以不给形参传值,因为在func函数的内存块里,变量a,b,c已经存在默认值了
- # a=1,b=2,c=3
- '''
- 像a=1,b=2,c=3这样给变量赋值了, 就叫他默认参数,也叫做缺省参数,default参数。实际上,默认参
- 数也是位置参数,可以这么说,位置参数给他赋上初值就成了默认参数。赋初值之后就可能没必要再用实
- 参来给他赋值了
- '''
ps:默认参数和关键字参数的区别
- def func(a=1, b=2, c=3): # a,b,c就是默认参数
- print(f'a={a},b={b},c={c}')
-
- #采用关键字参数传递参数,位置可以乱放,也就是a=1, b=2, c=3三者可以任意组合。
- func(a=1, b=2, c=3) # 这里的a,b,c就是关键字参数
- func(a=1, c=3, b=2) # 这里的a,b,c就是关键字参数
- func(b=2, a=1, c=3) # 这里的a,b,c就是关键字参数
- func(b=2, c=3, a=1) # 这里的a,b,c就是关键字参数
- func(c=3, a=1, b=2) # 这里的a,b,c就是关键字参数
- func(c=3, b=2, a=1) # 这里的a,b,c就是关键字参数
- '''
- 从上面的代码发现,默认参数和关键字参数的代码写法形式相同,都是:变量名 = 值/引用。
- 主要区别就是写的位置不同:
- 1,默认参数是写在函数定义时函数名后面括号里的,是形参;
- 2:关键字参数是调用函数时写在函数名后面括号里的,是实参。
- '''
- # 运行结果如下
- # a=1,b=2,c=3
- # a=1,b=2,c=3
- # a=1,b=2,c=3
- # a=1,b=2,c=3
- # a=1,b=2,c=3
- # a=1,b=2,c=3

- def func(a, b, c):
- print(f'a={a},b={b},c={c}')
- func(1, 2, 3) # a=1,b=2,c=3
- # a,b,c就是位置参数,变量a只接收一个实参那就是1,他不能把2,3都拿来,假如他把2,3都拿来的话,
- b,c就没有值了
-
- def func1(*args):
- print(f'args={args},args的类型是{type(args)}', '解包后是{0},{1},{2}'.format(*args))
- func1(1, 2, 3)
- # 执行结果是:args=(1, 2, 3),args的类型是<class 'tuple'>解包后是1,2,3
- '''
- args就是不定长位置参数,变量args是一个元组,他的值是(1, 2, 3),符号*是序列解包符号。由此可
- 见,不定长参数就是可以吃掉很多个实参的形参,例如args把实参1,2,3都接收了。
- '''
- def func(**kwargs):
- print(f'kwargs的值是{kwargs},\tkwargs的类型是\
- {type(kwargs)},', '\tkwargs的解包', kwargs.items())
-
-
- func(key1=1, key2=2)
- # 打印结果:
- # kwargs的值是{'key1': 1, 'key2': 2}, args的类型是<class 'dict'>, kwargs的解包 dict_items([('key1', 1), ('key2', 2)])
- '''
- 变量kwargs就是不定长关键字参数,是一个形参,它能够接收多个关键字实参,
- kwargs的类型是字典dict,用item方法来解包。上面的代码中,kwargs把key=1,key2=2都接收了
- '''
- def test1(a,b=1,c):
- return a+b+c
- test1(1,2,3)
- #上面的也会报错
- def test(a=10, b): # 这里把默认参数a放在位置参数b之前,会报错
- return a + b
-
- re = test(10, 10)
- print(re)
-
- '''
- def test(a=10,b1):
- ^
- SyntaxError: non-default argument follows default argument
- '''
- '''
- # 报错,提示'语法错误:非默认参数紧跟在在默认参数之后'。原因就是,默认参数可以不给他传值
- ,假如我们调用test1(2,3),假如把2赋值给形参a,那么3是赋值给b还是赋值给c是有歧义的。
- '''

但是,可以在默认参数和位置参数之间插入一个不定长位置参数:
- def test(a=10, *args, b): # 这里把默认参数a和位置参数b中间插入一个可变位置参数,就不会报错
- print(args)
- return a + b
-
-
- re = test(10, 10, b=10)
- print(re)
-
- # 运行结果
- # (10,)
- # 20
- def test(a, b=10):
- return a + b
-
- re = test(a=10, 10) # 这里把位置实参放在关键字参数之后,会报错
- print(re)
-
- '''
- re = test(a=10, 10)
- ^
- SyntaxError: positional argument follows keyword argument
- '''
- # 报错,提示''语法错误:位置实参在关键字参数之后''
这里就记住一句话:带等号的参数最好别放在括号里的最前面。
不定长关键字参数必须放在最后面。
像下面这样,a是位置参数,c是默认参数,*args是不定长位置参数,**kwargs是不定长关键字参数。前三种形参的位置可以任意组合,关键字可变参数必须放在最后面。
- def test0(a, c=10, *args, **kwargs):
- print(f'a={a}, c={c}, args={args}, kwargs={kwargs}')
-
-
- def test1(a, *args, c=10, **kwargs):
- print(f'a={a}, c={c}, args={args}, kwargs={kwargs}')
-
-
- def test2(c=10, *args, a, **kwargs):
- print(f'a={a}, c={c}, args={args}, kwargs={kwargs}')
-
-
- def test3(*args, a, c=10, **kwargs):
- print(f'a={a}, c={c}, args={args}, kwargs={kwargs}')
-
-
- def test4(*args, c=10, a, **kwargs):
- print(f'a={a}, c={c}, args={args}, kwargs={kwargs}')
-
-
- if __name__ == '__main__': #
- test0(1, 2, 3, key=1)
- test1(1, 2, 3, key=1)
- test2(1, 2, a=3, key=1)
- test3(1, 2, a=3, key=1)
- test4(1, 2, a=3, key=1)
- # a=1, c=2, args=(3,), kwargs={'key': 1}
- # a=1, c=10, args=(2, 3), kwargs={'key': 1}
- # a=3, c=1, args=(2,), kwargs={'key': 1}
- # a=3, c=10, args=(1, 2), kwargs={'key': 1}
- # a=3, c=10, args=(1, 2), kwargs={'key': 1}

首先,默认参数可以不给他传递实参。
- def add(a, b=10):
- print('a:', a, 'b:', b)
- return a + b
-
-
- re = add(1)
- print(re) # 打印11,这里把1传给a
- re1 = add(1, 2)
- print(re1)
- # a: 1 b: 10
- # 11
- # a: 1 b: 2
- # 3
另外,不定长位置参数会吃掉他对应位置之后所有的位置实参:在下面的代码中,不定长位置参数args会吃掉位置实参1,2,3,4,导致b和a没有被赋值。可以看出不定长的意思就是说并不知道到底有多少个参数传进来,但是不管多与少,都要接收。
- def test(*args, b, a, c=10, **kwargs):
- print(f'a={a}, c={c}, args={args}, kwargs={kwargs}')
-
-
- test(1, 2, 3, 4, key1=5, key2=6)
- # TypeError: test() missing 2 required keyword-only arguments: 'b' and 'a'
正确代码如下,在args后面的位置形参都需要使用关键字参数(强制命名参数)来赋值。
- def test(*args, b, a, c=10, **kwargs):
- print(f'a={a}, c={c}, args={args}, kwargs={kwargs}')
-
-
- test(1, 2, b=3, a=4, key1=5, key2=6)
-
- # a=4, c=10, args=(1, 2), kwargs={'key1': 5, 'key2': 6}
在上图中,没有给c传值,但是打印出c等于10,原因就是c的默认值为10。
若有错误,恳请大家指正。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。