7、Python之函数
一、函数的定义
python中函数的定义如下:
1 def fun(name): 2 print("%s你好" % name) 3 return name
用关键字def来定义函数,name为函数的形式参数简称形参,return表示将后面的变量返回给调用者。函数的特性是:1、减少重复代码 2、程序可扩展 3、程序可维护
下面我们针对函数的实参和返回值进行详细理解。
一、函数的实参
1 def fun_1(): #定义一个实参为空的函数 2 print("hello,world") 3 return 4 def fun_2(name): #定义只有一个形参的函数 5 print(name) 6 return 7 def fun_3(name,age): #定义有2个形参的函数 8 print("your name is %s,your age is %s" % (name,age)) 9 return 10 def fun_4(*args): #定义了一个可变形参(可传列表)的函数, 11 print(args) 12 return 13 def fun_5(**kwargs): #定义了一个可传字典的函数 14 print(kwargs) 15 return 16 def fun_6(x,y,f): #f为函数名称 这种函数称为高阶函数 17 print( f(x)+f(y)) 18 def f(x): 19 return x*x 20 #各种形式的函数对应的调用 21 fun_1() 22 fun_2("高文祥") #执行结果hello,world 23 fun_3("高文祥",18) #执行结果your name is 高文祥,your age is 18 24 fun_4(1,2,3,"高文祥")#执行结果 (1, 2, 3, '高文祥') 25 fun_4(*[1,2,3,4,5,"测试"])#执行结果 (1, 2, 3, 4, 5, '测试') 26 fun_5(name="高文祥",age=20)#执行结果{'name': '高文祥', 'age': 20} 27 fun_5(**{'name':'高文祥','age':18})#执行结果{'name': '高文祥', 'age': 18} 28 fun_6(2,3,f) #执行结果13
以上就是形式参数传递不同时的函数形式。为了更方便理解,我们首先引入一个很重要的概念:函数名就是“变量“,函数体就是变量的值,我们通过下面的代码来理解一下:
1 def add(x,y): 2 print(x+y) 3 return 4 count = 10
上面这段代码我们定义了一个函数和一个变量,函数名为add,变量名为count,之前我们说过函数名就是“变量”,函数体就是变量的值,按照这样的思路,我们可以画出上面的代码在内存中的存储方式:
这时候我们添加下面2条语句:
1 p = add 2 p(3,2)
当python解释器执行p = add时,无非就是将p指向了函数体的代码块,所以执行p(3,2)当然成立。
二、函数返回值
1 def fun_1(): #没有返回值的函数 也称过程 2 pass 3 def fun_2(): #不返回 4 pass 5 return 6 7 def fun_3(x,y): #返回多个参数 8 x = x*x 9 y = y*y 10 return x,y 11 def fun_4(): #返回一个函数 这种的也称高阶函数 12 return f 13 def f(x,y): 14 return x+y 15 #-----------------------调用-------------- 16 print(fun_1()) #执行结果 None 17 print(fun_2()) #执行结果 None 18 print(fun_3(4,5)) #执行结果 (16, 25) 19 print(fun_4()(1,2)) #执行结果3
三、嵌套函数
如果某个函数在其函数体内又定义了其它函数,这种函数称为嵌套函数,其写法如下:
1 def fun_01(name): #嵌套函数 2 def fun_02(name): 3 print(name) 4 fun_02(name) 5 fun_01("helen") #执行结果helen
四、递归函数
递归函数函数就是函数自己调用自己,如果这个函数没有一个结束点,那么这个运行将进入一个死胡同,永远没有停止,递归函数的语法如下:
1 def fun(n): 2 return fun(n-1)
递归函数的最大优点是其可以将很复杂的事情简单化,当然他是以消耗时间和内存作代价的,每一次的递归都需要生成一个栈。我们下面使用递归函数来实现数学中阶乘的运算:
1 def fun(n): #计算阶乘 2 if n == 1: 3 return 1 4 return n*fun(n-1) 5 print(fun(4)) #执行结果 24
递归的特性如下:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
五、匿名函数
匿名函数是没有函数名的函数使用关键字lambda
,其定义如下:
lambda n:n+1 #定义一个匿名函数
如果只是这样看的话,匿名函数其实并没有什么卵用,为了使他有点卵用,我们通常这样使用匿名函数
f = lambda x,y:x+y print(f(2,5)) #执行结果7
我们还可以这样使用:
1 res = map(lambda x:x**2,[1,5,7,4,8]) 2 for i in res: 3 print(i) #执行结果1,25,49,16,64 因为这里是一个map 所以数据是随机的
六、函数传参
函数传参有两种方式:1、位置参数 2、关键字参数
1 def fun_1(x,y,z): 2 print("x=%s,y=%s,z=%s"% (x,y,z)) 3 #执行------ 4 fun_1(1,2,3) #通过参数的位置调用,这种称为位置参数 执行结果x=1,y=2,z=3 5 fun_1(x=1,z=3,y=4) #通过形参来指定值,称为关键字参数 执行结果 x=1,y=4,z=3 6 fun_1(3,z=3,y=2) #包含位置参数和关键字参数
今天写的有点多了,扛不住了,最后再看一个默认参数,默认参数的意思是说,再函数调用的时候,默认参数可传,可不传,不传使用默认值,传了使用传递过来的值。
1 def fun_1(x,y,z,w=10): #w为默认参数,默认参数一定是放在最后的 2 print("x=%s,y=%s,z=%s,w=%s"% (x,y,z,w)) 3 #执行------ 4 fun_1(1,2,3) #执行结果x=1,y=2,z=3,w=10