什么是函数?
函数就是执行特定任务和以完成特定功能的一段代码
为什么需要函数?
复用代码
隐藏实现细节
提高可维护性
提高可读性便于调试
函数的创建
def 函数名 ([输入参数]) :
函数体
[return xxx]
函数名需要遵循字母、数字、下划线
# 这里的a,b是形式参数-形参,形参的位置是在函数的定义处 def calc(a,b): c = a+b return c print(calc(10,50)) # 60 这里的10,50称为实际参数的值,简称实参 print(calc(b=50,a=10)) #=左侧的变量名称为关键字参数,自动找a和b
定义函数取奇偶数
def fun(num): odd = [] # 存奇数 even = [] # 存偶数 for i in num: if i%2: odd.append(i) else: even.append(i) return odd,even lst=fun([10,21,33,66,88,99]) print(lst) # ([21, 33, 99], [10, 66, 88])
如果函数没有返回值【函数执行完毕之后,不需要给调
用处提供数据,return是可以省略不写的~
函数的返回值,如果是1个,直接返回类型
函数的返回值,如果是多个,返回的结果为元组
函数的参数定义
函数定义默认值参数
函数定义时,给形式参数设置默认值,只有与默认值不符的时候才需要传递实参
def fun(a,b=10) print(a,b) fun(100) #只传一个参数,b采用默认值 fun(20,30) #30将默认值10替换
个数可变的位置参数
定义参数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数
使用*定义个数可变的位置形参
只能定义一个,def fun(* args,*a):这样报错
结果为一个元组
def fun(*args): # 函数定义时的 可变的位置参数 print(args) fun(10) fun(10,30) fun(30,405,50) """ 结果 (10,) 注意元组有, 逗号,否则为字符串了 (10, 30) (30, 405, 50) """
个数可变的关键字形参
定义函数时,无法事先先确定传递的关键字实参的个数时,使用可变的关键字形参
使用**定义个数可变的关键字形参
只能定义一个,def fun(** args, **a):这样报错
结果为一个字典
def fun1(**args): print(args) fun1(a=10) # {'a': 10} fun1(a=20,b=30,c=40) # {'a': 20, 'b': 30, 'c': 40}
print源码
它是一个形式可变的位置参数,所以print('这里写几个都没问题')
defprint(self, *args, sep=' ', end='\n', file=None):
注意
在一个函数定义过程中,既有个数可变的关键字形参,也有个数可变的位置形参,要求,个数可变的位置形参,放在个数可变的关键字形参之前
def fun(**args1,*arg2):
在函数调用时的参数传递,称为位置传参
def fun(a,b,c): print(a,end='\t') print(b,end='\t') print(c,end='\t') fun(10,20,30) # 10 20 30 函数调用时的参数传递,称为位置传参 lst = [11,22,33] # fun(lst) #报错 fun(*lst) # 11 22 33 在函数调用时,将列表中的每个元素都转换为位置实参传入 dic = {'a':111,'b':222,'c':333} # fun(dic) #报错 fun(**dic) # 111 222 333 在函数调用时,将字段的键值对都转换为关键字实参传入 # 个数可变的关键字传参 def fun4(**args): print(args) fun4(a=666,b=888) # {'a': 666, 'b': 888}
函数传参其它类型
def fun5(a,b,*,c,d): print(a) print(b) print(c) print(d) fun5(a=10,b=20,c=30,d=40) # 10 20 30 40 # fun5(10,20,30,d=40) # 错误 前两个参数采用的是位置实参传递,c,d只能采用关键字传递 fun5(10,20,c=30,d=40) # 10 20 30 40 # 这些也都是可以的 def fun5(a,b,*,c,d,**args): print(args) fun5(1,3,c=3,d=4,e=4) # {'e': 4} def fun(*args,**args2): pass def fun(*args,**args2): pass def fun(a,b=10,*args,**args2): pass
变量的作用域
程序代码能访问该变量的区域
根据变量的有效范围可分为
局部变量和全局变量
局部变量
在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会成为全局变量
全局变量
在函数体外定义的变量,可作用函数内外
def fun(): global age # 声明global在外部也可以使用了 age=20 print(age) # 20fun()print(age+1) # 21
递归函数
什么是递归函数?
在函数体内调用了函数本身
递归的组成部分
递归调用与递归终止条件
递归的调用过程
每递归调用一次函数,都会在栈内存分配每一个栈帧
每执行完一次函数,都会释放相应的空间
递归的优缺点
优点:占用内存多,效率低下
缺点:思路和代码简单
练习:斐波那契数列
(形如1 1 2 3 5 8..每一项都前两项之和的数列)
# 斐波那契数列 def fib(n): if n == 1 or n == 2: return 1 else: return fib(n-1)+fib(n-2) print(fib(3)) # 2 # 输出前四项数组 for i in range(1,5): print(fib(i)) # 1 1 2 3