
Python 基础三
Python 函数
知识要点
1、函数的简介
如果在开发过程中,需要某块代码多次,为了提高编写效率以及代码重用,所以把具有独立功能的代码块组建为一个小模块,这就是函数。python中提供了许多内建函数,如print()。用户可以自定义函数。
例如:计算圆的面积 S = $\pi r ^2$
1 | r1 = 12.34 |
2、函数的定义和调用
(1) 定义函数
定义函数格式如下:
1 | def 函数名(参数[可选]): |
(2) 调用函数
定义函数滞后,相当于有了一个具有某种功能的代码,想要让这些代码能够执行,需要调用它,调用函数很简单,通过 函数名() 即可完成调用。
1 | # 定义函数后,函数不会自动执行,需要调用它才可以 |
(3) 注意:
- 每次调用函数时,函数都会从头开始执行,当这个函数中的代码执行完毕后,意味着调用结束了
- 如果函数中执行了 return 也会结束函数
3、函数的文档说明
1 | def test(a,b): |
4、函数的参数
Python 的函数定义非常简单,但灵活度非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使用函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。
1、位置参数
我们先写一个计算 x^2 的函数:
1 | def power (x): |
对于 power() 函数,参数 x 就会一个位置参数。
当调用 power 函数时,必须传入且仅有一个参数 x
1 | power(5) |
现在,如果我们要计算 $x^3$ 怎么办?可以再定义一个 power3 函数,但是如果要计算 X^4, X^5……怎么办?我们不能定义无限多个函数。
定义 power(x,n)
1 | def power(x,n): |
对于这个修改后的 power(x,n) 函数,可以计算 n 次方
1 | power(5,2) |
修改后的 power(x,n) 函数有两个参数:x , n ,这两个参数都是位置参数,调用函数时,传入的两个值按照位置顺序赋值给 x 和 n 。
2、默认参数
新的 power(x,n)函数定义没有问题,但是就得代买失效了,原因是我们增加了一个参数,导致就得代码缺少一个参数而无法正常调用:
1 | power(5) |
这个时候,就要使用默认参数进行定义,
1 | def power(x,n=2): |
这样,当我们调用 power(5) 时,就会默认为 power(5,2)
以上例子可以看出,默认参数可以简化函数调用。设置默认参数时要注意
- 必选参数在前,默认参数在后,或者都是默认参数,否则报错
- 当函数有多个参数时,把变化大的参数放在前面,变化小的参数放在后面,变化小的参数可以作为默认参数。
3、使用默认参数的好处
例子:小学生注册的函数,需要传入 name 和 gender 两个参数:
1 | def enroll(name,gender): |
这样调用 enroll() 函数只需要传入两个参数
1 | enroll('Sarah','F') |
如果要继续传入年龄、城市信息怎么办,这样会使得调用函数的复杂度加大
我们可以吧年龄和城市设为默认参数
1 | def enroll(name,gender,age=6,city="Beijing") |
这样大多数学生在注册时不需要再提供年龄和城市,只需要两个参数
1 | enroll('Sarah','F') |
只有与默认参数不符合的学生才需要额外提供信息
1 | enroll('Bob','M',7) |
可见,默认参数降低了函数调用难度,而一旦需要复杂调用时,又可以传递更多的参数来实现。意思是,除了 name ,gender 两个参数外,最后一个参数应用在 age city参数由于没有提供,任然是默认值。
也可以不按顺序提供部分默认参数。当不按顺序提供部分默认参数时,需要把参数名写上。比如 enroll(‘Adam’,’M’,city=’Tianjing’) city 参数时传进去的,其他为默认值。
注意:默认参数有个大坑,如下
先定义一个函数,传入一个list,添加一个END 再返回:
1 | def add_end(L=[]): |
结果似乎不错
1 | add_end([1,2,3]) |
使用默认参数调用时,开始结果是对的
1 | add_end() |
但是,再次调用就出问题了:
1 | add_end() |
解释:Python函数在定义的时候,默认参数L的值就被计算出来了,即[], 因为默认L 也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,默认的呢绒就变了,不再是函数定义时的[]了。
- 默认参数必须指向不变对象
1 | def add_end(L=None): |
那么无论调用多少次都没问题了。
str,None 这样的不变对象,对象内部数据不能修改,可以减少由于修改数据导致的错误。此外,由于对象不变,多任务环境下读取对象不需要加锁,同时读取一点问题没有。如果可以设计一个不变对象,尽量设计成不变对象。
4、可变参数[list 或 tuple]
在pyrhon 中还可以定义可变参数。传入的参数个数是可变的
1 | def calc(*numbers): |
1 | # 如果已经有了一个list 或tuple |
5、命名关键字参数[字典]
对于关键字参数,调用者可以传入任意个不受限制的关键字参数
1 | def person(name,age,**kw): |
6、参数组合
在python中,必选参数、默认参数、可变参数、关键字参数、命名关键字参数。组合使用也是可以的,但是必须按照以上的殊勋。
5、函数返回值
return
一个函数有多个返回:
1 | def divid(a,b): |
6、递归函数
函数内部,自己调用自己
1 | # 递归(自己调用自己) |
7、局部变量
- 局部变量:在函数内部定义的函数
- 作用范围在这个函数内部。
- 作用:为了零时保存数据需要在函数定义变量来进行存储
- 当函数调用时,局部变量呗创建,当函数调用完成后这个变量就不能用了
8、全局变量
一个变量既能在一个函数中使用,也能在其他函数中使用,全局变量
在函数外定义的变量就是全局变量
全局变量能够在所有函数中进行访问
- 当函数内出现局部变量和全局变量重名时,函数内部的 变量名 = 数据 可以理解为一个局部变量而不能修改全局变量。
- 修改全局变量 globle XX
1 | # 局部变量和全局变量: 在函数里面的定义的变量就是局部,外面就是全局 |