函数基础
函数
主要内容
- 函数的定义
- 函数的返回值
- 函数的参数
函数的定义
在Python中,我们可以在任何地方直接调用内置方法len求一个容器类型(可迭代类型)的元素个数,这个内置方法len就是一个函数。函数就是一段封存了固定代码的代码段,函数具有特定的功能,当我们调用函数,它就会执行,然后完成我们的任务。注意函数在定义后只是保存到内存中,只有我们主动通过函数名+括号的方式去调用它,函数才会执行内部代码。函数的定义方式是通过关键字def定义的,具体形式如下所示:
def get_sum(a, b):
"""求和"""
print(a, b)
return a+b
可以看出函数定义的时候必须指定函数名,然后加上一对括号,里面可以传入参数,也可以不传参数,接着加上冒号,同if with while等一样,接下来缩进的代码属于函数体,属于这个函数,里面实现函数的具体功能,最后可以有返回值,可以返回给调用者。
值得注意的是函数在定义的时候解释器只会检测语法的错误,不会执行检测内部的逻辑错误。函数的调用方式前面也说过了,就是通过函数名加一对小括号和参数
调用,如此可见函数名其实同变量一样,都相当于一个引用,指向一段内存地址,只不过函数更复杂罢了。
函数的返回值
刚刚说完了函数的简单定义方式,接下来总结下函数的返回值情况。python中的函数返回值有多种情况,但无论怎样,要记住Python的函数一定是有返回值的。
1. 当函数执行结束后,整个函数体都没有出现return关键字,那么函数会默认返回None
2. 函数的某处只写了return关键字,那么此时函数也会返回None,这里的return一般带有主动结束函数的作用,例如这里的return语句处于多层循环中,就不用麻烦的break跳出循环了,只需要return语句就能中断。
3. 函数可以返回一个值或多个值,Python中的函数可以返回任意数据类型,其中只返回一个值时,Python不会做处理,当返回一个以上的值时,会把这多个值打包成一个元组返回给调用者,这里用元组一个是因为不可变,还有就是元组相对其他容器类型更节省内存。
def get_sum(a, b):
"""求和"""
return a, b, a + b
print(get_sum(1, 2))
(1, 2, 3)
函数的参数
参数的概述
函数定义的时候,括号里写的类似变量的就是函数的参数,叫作形式参数,简称形参,在我们调用函数的时候,也需要给函数传参数,这时候传的参数就叫做实际参数,简称实参。实参和形参的关系可以这么理解,形参在函数定义的时候就只是个变量名,还没有任何意义,当我们传入实参给函数的时候,这时候实参就相当于值,并赋值给形参。
函数定义时的形式参数也比较复杂,主要分为以下几种类型。
参数的类型
1. 位置参数
所谓位置参数就是函数定义时,只有变量名表示的参数位置,就是def(a, b)这样的形式定义的,这里a,b就是位置参数,以位置参数定义的时候,我们调用的时候也必须保证传入的时候一一对应,且传入实参不能多也不能少,否则都会抛出异常。
def test(a, b):
print(a, b)
test(2, 4)
test(b=4, a=2)
test(2, b=4)
test(b=4, 2) # positional argument follows keyword argument
作为调用者,传入方式主要有以上几种,第一个就是按照参数的具体意义一一对应传入,正如其名位置参数一样。第二个就是可以使用关键字参数传参数,这时候可以不用与形参变量名的位置一一对应,但是传入的参数还必须一样多。第三种就是关键字参数可以和位置参数混合传入给形参,此时需要注意的点就是位置参数必须在前面,否则就会报错。就像上面最后一个测试例子一样。
2. 默认参数
def line(x, a=1, b=0):
"""求线性函数的值"""
return a * x + b
print(line(1))
print(line(1, 2))
print(line(1, 2, 3))
1 2 5
默认参数就是函数在定义的时候默认参数就已经初始化好了,默认参数已经指向了一处内存空间了,然后就不会外界因素改变指向地址了。默认参数的特性是调用者传值后,会使用调用者传的实参的值,否则就会使用默认值。效果就如同上面的例子一样。
下面是一个默认参数的小坑
m = 10
def func(x=m):
print(x)
func() # 输出是10
m = 20
func() # 输出同样是10
这里的核心就是要理解默认参数在定义时就指向了整数10所在的内存地址,m变量也只是一个整数10的其中一个引用,下面m重新赋值只是重新指向了20的内存地址,与默认参数x无关,所以上面的输出都是10.
3. 可变长参数
所谓可变长,就是指代调用者可以传入不定长个参数给函数。Python中可变长参数分为2种,一个可变长位置参数,还有就是可变长关键字参数。它们都是通过 * 号这个运算符来实现的,其中可变长位置参数的写法是变量名前面加一个 * 号, 可变长关键参数是变量名前面加两个 * 号,不过这两种参数一般都是有Python推荐的固定名称的,就是*args,和**kwargs。
它们的功能就是 :
* args 能够接收调用者传给函数多余的位置参数,并以元组的形式接收。
**kwargs 能够接收调用者多余的关键字参数,并以字典的形式接收。
def func(a, *args, **kwargs):
print(a, args, kwargs)
func(1, 2, 3, 4, name='jack', price=100)
1 (2, 3, 4) {'name': 'jack', 'price': 100}
上面的例子就是把多余的2, 3, 4位置参数给打包成元组传递给形参了,而两个关键字最后也确实是 以字典的形式呈现的。
此处再补充一个* 和 ** 运算符的特殊用法,就是它们可以解压打散对应的容器类型,然后把每一个实参传入函数中。
def func(a, *args, **kwargs):
print(a, args, kwargs)
func(1, *'str', **{'name': 'egg', 'price': 20})
1 ('s', 't', 'r') {'name': 'egg', 'price': 20}
效果与上述一个个传一样。

浙公网安备 33010602011771号