查缺补漏系列(三)--------函数的参数

定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义
就完成了。对于函数的调用者来说,只需要知道如何传递正确的参数,
以及函数将返回什么样的值就够了。
Python 的函数定义非常简单,但灵活度却非常大。除了正常定义的必选
参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义
出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。
1.位置参数
有一个计算x2 的函数:

def power(x):
    return x*x

这里的x就是位置参数,现在,如果我们要计算 x3 怎么办?可以再定义一个 power函数,也可以把 power(x)修改为 power(x, n),用来计算 xn,减少了代码量。

def power(x, n):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

2.默认参数
新的 power(x, n)函数定义没有问题,但是,旧的调用代码失败了,原因
是我们增加了一个参数,导致旧的代码因为缺少一个参数而无法正常调
用:

F:\Python37-32\python.exe F:/python文件/exercise3.py
Traceback (most recent call last):
  File "F:/python文件/exercise3.py", line 7, in <module>
    print ( power(5))
TypeError: power() missing 1 required positional argument: 'n'

这时候我们就有可能用到默认参数,默认 n = 2 ,然后更方便我们的操作。

def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s
print ( power(5))

使用默认参数最大的好处是能降低调用函数的难度。默认参数很有用,但使用不当,也会掉坑里。默认参数有个最大的坑,
演示如下:
先定义一个函数,传入一个 list,添加一个 END 再返回:

>>> add()
['END']
>>> add()
['END', 'END']

会发现明明传入的是空列表,但却加了两遍,原因解释如下:
Python 函数在定义的时候,默认参数 L 的值就被计算出来了,即[ ],因
为默认参数 L 也是一个变量,它指向对象[ ],每次调用该函数,如果改
变了 L 的内容,则下次调用时,默认参数的内容就变了,不再是函数定
义时的[ ]了。
3.可变参数
在 Python 函数中,还可以定义可变参数。顾名思义,可变参数就是传
入的参数个数是可变的,可以是 1 个、2 个到任意个,还可以是 0 个。
我们以数学题为例子,给定一组数字 a,b,c……,请计算a2+b2+c2+…
要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,
我们首先想到可以把 a,b,c……作为一个 list 或 tuple 传进来,这样,
函数可以定义如下:

>>> def calc(numbers):
	sum = 0
	for n in numbers:
	    sum = sum + n * n
	return sum

>>> calc([1,2,3])
14

如果利用可变参数,调用函数的方式可以简化成这样:

>>> calc(1, 2, 3)
14

所以,我们把函数的参数改为可变参数:

>>> def calc(*numbers):
	sum = 0
	for n in numbers:
	    sum = sum + n * n
	return sum

如果已经有一个 list 或者 tuple,要调用一个可变参数怎么办?可以这样
做:

>>> nums = [1, 2, 3]
>>> calc(*nums)
14

4.关键字参数
关键字参数允许你传入 0 个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个 dict。

def person(name, age, **kw):
 print('name:', name, 'age:', age, 'other:', kw)

函数 person 除了必选参数 name 和 age 外,还接受关键字参数 kw。在调
用该函数时,可以只传入必选参数:

>>> def person(name,age,**kw):
	print("name:",name,"age:",age,"other:",kw)

	
>>> person("wangda",30)
name: wangda age: 30 other: {}
>>> person("long",14,country = 'China')
name: long age: 14 other: {'country': 'China'}

它可以扩展函数的功能。比如,在 person 函数里,我们保证能接收到 name 和 age 这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。和关键字参数**kw 不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错.

def f1(a, b, c=0, *args, **kw):
	print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
def f2(a, b, c=0, *, d, **kw):
	print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
>>> f1(1, 2)
a = 1 b = 2 c = 0 args = () kw = {}
>>> f1(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> f1(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}

Python 的函数具有非常灵活的参数形态,既可以实现简单的调用,又可
以传入非常复杂的参数。默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
要注意定义可变参数和关键字参数的语法:
*args 是可变参数,args 接收的是一个 tuple;
**kw 是关键字参数,kw 接收的是一个 dict。

发布了37 篇原创文章 · 获赞 42 · 访问量 4515

猜你喜欢

转载自blog.csdn.net/qq_43337175/article/details/104346363