您当前的位置: 首页 >  编程语言

函数的参数

定义函数时()里的参数叫做形参(形式参数),它只是一个变量名,接受调用时传递的实参,仅供函数体中的代码调用。

函数调用时,传入()里的参数叫实参(实际参数),它是实际的数据,会传递给形参。

形参

根据形参的功能和定义方式可以分为:

必须参数 默认参数 动态参数 位置动态参数 关键字动态参数 必须参数

在定义函数时,如果要求调用者必须传递实参给这个形参,那么这个形参就要定义为必须形参。

直接定义在函数名后的()里的形参就是必须形参。

例如上一节中的my_print函数中的content和count。我们再来看一个案例:

定义一个函数,接收两个数,然后打印它们的和

>>> def add(x,y):
...     print(x+y)
>>> add(1)		# 调用时必须传递实参给必须参数,否则报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() missing 1 required positional argument: 'y'
>>> add(1,2)
3
默认参数

在定义函数时,某些形参有默认值,在调用时可以不接收实参,这种情况就可以定义为默认形参。

在函数名后()中,以参数名=默认值的形式定义的形参就是必须参数。

注意:默认参数必须定义在必须参数的后面

案例:

定义一个函数,它接收两个参数content和count

content是函数要打印的内容

count是函数打印的次数,如果不传递count默认打印1次

>>> def my_print(content, count=1):
...     for i in range(count):
...        print(content)
# 调用
>>> my_print('好好学习,天天向上!')
'好好学习,天天向上!'
>>> my_print('好好学习,天天向上!', 2)
'好好学习,天天向上!'
'好好学习,天天向上!'

调用函数时传递实参给默认形参会覆盖默认值。

动态参数

在定义函数时,不确定在调用时会传递多少个实参,可以定义为动态形参。

动态形参根据实参的传递方式又分为两种。

位置动态参数

在函数名后的()中,在形参前加*号,这个形参就被定义为位置动态参数,通常位置动态参数的参数名为args。

它用来接收函数调用时,以位置形式传递过来的超过形参数量的多余的实参。

注意:位置动态参数必须定义在默认参数后面。

位置动态参数会将所有多余的位置实参创建成一个元组。

>>> def func(a, *args):
...     print(args, type(args))
>>> func(1,2,3,4)
(2, 3, 4) <class 'tuple'>

案例:

定义一个函数,接受2个以上的数,打印它们的和。

>>> def add(x, y, *args):
...     sum = x + y
...     for i in args:
...         sum += i
...     print(sum)
>>> add(1, 2, 3, 4)
10
关键字动态参数

在函数名后的()中,在形参前加**号,这个形参就被定义为关键字动态参数,通常关键字动态参数的参数名为kwargs。

它用来接收函数调用时,以关键字形式传递过来的超过形参数量的多余的实参。

注意:关键字动态参数必须定义在位置动态参数的后面。

关键字动态参数会将多余的关键字实参创建成一个字典

>>> def func(a, **kwargs):
...     print(kwargs, type(kwargs))
>>> func(a=1,b=2,c=3,d=4)
{'b': 2, 'c': 3, 'd': 4} <class 'dict'>
实参

调用函数时传递实参有两种方式:

位置传递 关键字传递 位置传递

调用函数时,在小括号中以(实参1,实参2,...)的形式传递的实参会按照位置与形参一一对应,以这种方式传递的实参叫做位置实参。

案例:

定义一个函数实现打印一个数的n次幂。

>>> def my_power(x, n):
...     print(x**n)
>>> my_power(3,2)		# 3传递给x,2传递给n
9
>>> my_power(2,3)		# 2传递给x,3传递给n
8
关键字传递

调用函数时,在小括号中以(形参1=实参1,形参2=实参2,...)的形式,显式的指定形参与实参的对应关系,以这种方式传递的实参叫做关键字实参。

注意:关键字实参必须写在位置实参的后面。

案例:

使用关键字的方式调用my_power函数

>>> my_power(x=3,n=2)
9
>>> my_power(n=2,x=3)
9
>>> my_power(3,n=2)
9
参数解包

当一个函数接收多个参数时,如果参数存储在一个列表或一个字典中时,调用起来非常不方便。看下面的案例:

>>> def func(a, *args):
...     print(args, type(args))
>>> ls = [1,2,3,4,5,6]
>>> fun(ls[0],ls[1],ls[2],ls[3],ls[4],ls[5])
1 2 (3, 4, 5, 6)
>>> def func(a, **kwargs):
...     print(kwargs, type(kwargs))
>>> dc =  {'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>> fun(a=dc['a'], b=dc['b'], c=dc['c'], d=dc['d'])
1 2 {'c': 3, 'd': 4}

可以看到上面的案例调用时的不便,参数解包就是为了解决这些问题的。

*解包

在传递实参时,可以通过*对可迭代对象进行解包。

>>> func(ls[0],ls[1],ls[2],ls[3],ls[4],ls[5])
1 2 (3, 4, 5, 6)
>>> func(*ls)			# 与上面的写法等价
1 2 (3, 4, 5, 6)
**解包

在传递实参时,可以通过**对字典进行解包。

>>> fun(a=dc['a'], b=dc['b'], c=dc['c'], d=dc['d'])
1 2 {'c': 3, 'd': 4}
>>> fun(**dc)			# 与上面的写法等价
1 2 {'c': 3, 'd': 4}