一、函数的介绍
-
代码重用
-
保持一致,易于维护
-
可扩展性
二、函数的定义及调用
2.1 函数的定义
-
函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
-
任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数
-
函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明
-
函数内容以冒号起始,并且缩进
-
return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None
1 定义函数的语法: 2 3 4 def 函数名(参数): 5 函数体 6 返回值
1 # 示例 2 3 def print_hello(): 4 """ 5 打印hello 6 :return: 7 """ 8 print ( " hello " )
2.2 函数的调用
定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,需要调用它
调用函数很简单的,通过 函数名() 即可完成调用
1 # 示例: 2 print_hello() # 调用函数
注意:
- 每次调用函数时,函数都会从头开始执行,当这个函数中的代码执行完毕后,意味着调用结束了
- 当然了如果函数中执行到了return也会结束函数
三、函数的返回值
在函数中添加返回值,需要使用return关键字
1 def fun1(): # 无返回值 2 print ( " aa " ) 3 4 def fun2(): 5 msg = " hello world " 6 return msg # 返回msg,一个返回值 7 8 def fun3(): 9 return 1, 2, 3 # 返回多个返回值 10 11 aa = fun1() # 接收函数的返回值 12 bb = fun2() 13 cc = fun3() 14 print (aa) 15 print (bb) 16 print (cc) 17 18 # 输出结果: 19 # None 20 # hello world 21 # (1, 2, 3)
总结:
- 函数中如果没有return语句返回,那么python函数会默认返回None
- 函数返回值数为0,函数默认返回None;函数返回值数为1是,则返回object;返回值数大于1时,则返回的是一个tuple
四、函数的参数
-
形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量
-
实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值
-
位置参数和关键字(标准调用:实参与形参位置一一对应;关键字调用:位置无需固定)
-
默认参数:放在参数列表的最后
-
参数组
4.1 普通参数
1 def fun1(name): # name为形式参数 2 print (name) 3 4 aa = " hello " 5 fun1(aa) # aa为实参
4.2 默认参数
1 def func(name, age=18 ): 2 print ( " %s:%s " % (name, age)) 3 4 5 # 指定参数 6 func( ' aa ' , 19) # 自定义传入默认参数,以传入的为准 7 func( ' cc ' , age=20 ) 8 func( ' bb ' ) # 默认参数不传,使用默认值 9 10 # 运行结果: 11 # aa:19 12 # cc:20 13 # bb:18
4.3 动态参数
位置参数 > *动态参数 > 默认参数
1 def func1(* args): 2 print (args) 3 print (type(args)) #元组 4 5 6 # 执行方式一 7 func1(11, 33, 4, 4454, 5 ) 8 9 # 执行方式二 10 li = [11, 2, 2, 3, 3, 4, 54 ] 11 func1(*li)
1 def func2(** kwargs): 2 print (kwargs) 3 print (type(kwargs)) #4 5 6 # 执行方式一 7 func2(name= ' wupeiqi ' , age=18 ) 8 9 # 执行方式二 10 dict1 = { ' name ' : ' fyh ' , " age " : 18, ' gender ' : ' male ' } 11 func2(**dict1)
注意:
- 加了星号(*)的变量args会存放所有未命名的变量参数,args为元组
- 而加**的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典
1 # 万能参数 可以接收任意的参数 2 def func(*args, ** kwargs): 3 pass
五、函数的嵌套
1 def func1(): 2 print ( " hello world " ) 3 4 5 def func2(): 6 print ( " aa " ) 7 func1() 8 print ( " cc " ) 9 10 11 func2() # 按顺序执行 先执行print("aa") --> func1() --> print("cc")
六、全局变量与局部变量
6.1 命名空间与作用域
命名空间: 1 .内置命名空间:python解释内部运行时的变量函数 2 .全局命名空间:我们在py文件中直接声明出来的变量、函数 3 .局部命名空间:在函数内部声明的变量和函数 加载顺序: 1 .内置命名空间 2 .全局命名空间 3 .局部命名空间 取值顺序: 1 .局部命名空间 2 .全部命名空间 3 .内置命名空间 作用域: 1.全局作用域:全局命名空间 + 内置命名空间 2 .局部作用域:局部命名空间 可以通过globals()函数来查看全局作用域中的内容,也可以locals()查看当前作用域中的内容
6.2 全局变量与局部变量
1 # 示例 2 def fun1(): 3 name = " aa " 4 print (name)
报错的原因:试图访问局部变量而报的错
6.2.1 局部变量和全局变量名一样
- 全局变量与局部变量名一致,函数内部会优先使用局部变量
- 修改局部变量不会影响到全局变量
1 name = " bb " 2 def print_name(): 3 name = " aa " 4 print (name) 5 6 print_name() 7 print (name) 8 # 打印的结果为 9 # aa 10 # bb
6.2.2 global关键字
使用global关键字:则会告诉python编译器,这个变量是全局变量而不是局部变量,这样在函数体内修改变量会影响全局了
1 name = " bb " 2 def print_name(): 3 global name 4 name = " aa " 5 print (name) 6 print_name() 7 print (name) 8 # 打印的结果: 9 # aa 10 # aa
6.2.3 nonlocal关键字
1 def fun1(): 2 num = 1 3 4 def fun2(): 5 nonlocal num # 此处不能使用global,只能使用nonlocal 6 num += 1 7 return num 8 return fun2 9 10 11 aa = fun1() 12 print (aa())
七、函数名的本质
函数名本质上就是函数的内存地址
7.1 可以被引用
1 def func(): 2 print ( ' in func ' ) 3 4 5 f = func 6 print (f) #
7.2 可以被当作容器类型的元素
1 def f1(): 2 print ( ' f1 ' ) 3 4 5 def f2(): 6 print ( ' f2 ' ) 7 8 9 def f3(): 10 print ( ' f3 ' ) 11 12 13 l = [f1, f2, f3] 14 d = { ' f1 ' : f1, ' f2 ' : f2, ' f3 ' : f3} 15 # 调用 16 l[0]() 17 d[ ' f2 ' ]()
7.3 可以作为函数的参数或返回值
7.3.1 作为函数的参数
1 def func1(): 2 print ( " aa " ) 3 4 5 def func2(f2): 6 f2() 7 8 9 func2(func1) # 作为函数的参数
7.3.2 作为返回值
1 def func1(): 2 3 def func2(): 4 print ( " bb " ) 5 return func2 # 作为返回值 6 7 8 f = func1() 9 f()
八、匿名函数
语法格式: lambda [形参 1 ], [形参 2 ], ... : [单行表达式] 或 [函数调用]
1 # 不带参数 2 my_fun = lambda : 10 + 20 3 # 带参数 4 my_add = lambda a, b: a + b 5 my_add()
-
函数的参数可以有多个,多个参数之间用逗号隔开
-
匿名函数不管多复杂,只能写一行,且逻辑结束后直接返回数据
-
返回值和正常的函数一样,可以是任意数据类型
1 def my_function(func): 2 3 a = 100 4 b = 200 5 # 把 cucalate_rule 当做函数来调用 6 result = func(a, b) 7 print ( ' result: ' , result) 8 9 10 my_function( lambda a, b: a + b)
九、高阶函数
9.1 sorted 排序
语法:sorted(Iterable, key=None, reverse=
False)
Iterable:可迭代对象
key:排序规则(排序函数),在sorted内部会将可迭代对象中的每一个对象传递给这个函数的参数,根据函数的运算结果进行排序
1 lst = [5, 7, 6, 12, 1, 13, 9, 18, 5 ] 2 # lst.sort() # sort是list里面的方法 3 # print(lst) 4 new_lst = sorted(lst, reverse=True) # 内置函数,返回给你一个新列表,新列表是被排序的 5 print (new_lst) 6 7 8 # 给列表排序,按照字符串的长度进行排序 9 lst2 = [ " 大阳哥 " , " 尼古拉斯 " , " 赵四 " , " 刘能 " , " 广坤 " , " 谢大脚 " ] 10 11 12 def func(st): 13 return len(st) 14 15 16 new_lst = sorted(lst2, key=func) # 内部,把可迭代对象中的每一个元素传递给func 17 # new_lst = sorted(lst2, key=lambda x: len(x)) # 也可以使用匿名函数 18 print (new_lst)
9.2 filter 过滤
filter(过滤):遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来,组成新的迭代器
语法:filter(function, Iterable) 返回一个迭代器
function:用来筛选的函数,在filter中会自动的把iterable中的元素传递给function,然后根据function返回的True或者False来判断是否保留次数据
Iterable:可迭代对象
1 list1 = [ " 1111aaa " , " 2222aaa " , " 3333aaa " , " 4444 " , " 5555 " , " 6666 " ] 2 list2 = filter( lambda x: x.endswith( " aaa " ), list1) # 有过滤的作用 3 print (list(list2)) 4 # 运行结果:['1111aaa', '2222aaa', '3333aaa']
9.3 map 映射
语法:map(function, Iterable)
map处理序列中的每个元素,得到一个结果(迭代器),该迭代器元素个数与位置不变
1 list1 = [1, 2, 3, 4, 5 ] 2 list2 = map( lambda x: x+1, list1) # map的第一个参数为函数,后面的参数为可迭代对象 3 print (list(list2)) 4 # 结果:[2, 3, 4, 5, 6] 5 6 lst1 = [1, 2, 3, 4, 5 ] 7 lst2 = [2, 4, 6, 8, 9 ] 8 9 10 print (list(map( lambda x, y: x+ y, lst1, lst2))) 11 # 结果:[3, 6, 9, 12, 14]
9.4 reduce
reduce 处理一个序列,把序列进行合并操作
from functools import reduce list1 = [1, 2, 3, 4, 5 ] aa = reduce( lambda x, y: x+y, list1) # 前一个参数的函数必须是两个参数 print (aa) # 运行结果:15
十、递归函数
1 """ 2 1! = 1 3 2! = 2 × 1 = 2 × 1! 4 3! = 3 × 2 × 1 = 3 × 2! 5 4! = 4 × 3 × 2 × 1 = 4 × 3! 6 ... 7 n! = n × (n-1)! 8 使用递归实现 9 """ 10 11 12 def cal_num(num): 13 if num >= 1 : 14 result = num * cal_num(num - 1 ) 15 else : 16 result = 1 17 return result 18 19 20 print (cal_num(3))
执行原理:
递归的执行深度调整:
1 import sys 2 sys.setrecursionlimit(10000) # 可以调整递归深度,但是不一定跑到这里
# 斐波那契数列:就是前两个数的和为后一个数的值(0,1,1,2,3,5,8,13.........): # 计算第n个数的值 def foo(num): """ 实现斐波那契数列 :param num: 第几个数 :return: """ if num <= 0: return 0 elif num == 1 : return 1 else : return foo(num - 1) + foo((num - 2))