1. 函数对象
Python中所有的数据都是对象 , 函数的值也是一个对象 , 通过函数名获取函数对象 .
使用函数名也就是使用函数对象 , 函数对象加上括号立刻执行函数体代码块 .
函数名的其它作用 :
* 1. 函数名可以作为其它变量的值 .
* 2. 函数名可以作为其它函数的参数 .
* 3. 函数名可以作为函数的返回值 .
* 4. 函数名可以作为容器类型的的元素 .
1.1 引用函数变量
def func1 ( ) : print ( '1' )
func2 = func1
func2( )
1.2 做为参数
def func1 ( ) : print ( '1' ) def func2 ( func) : func1( )
func2( func1)
def func1 ( ) : print ( '1' ) def func2 ( ) : func1( ) func2( )
1.3 做为返回值
def func1 ( ) : print ( '1' ) def func2 ( ) : return func1func = func2( )
func( )
从外部范围隐藏名称xx .
Pycharm的提示需要重命名参数名称来消除这个警告 .
def func1 ( ) : print ( '1' ) def func2 ( fun_p) : return fun_pfunc = func2( func1)
func( )
def func1 ( ) : print ( '1' ) def func2 ( ) : return func1func = func2( )
func( )
1.4 做为容器元素
def add_staff ( ) : print ( '添加员工' )
def del_staff ( ) : print ( '删除员工' ) func_dic = { '1' : add_staff, '2' : del_staff}
func_dic[ '1' ] ( )
func_dic[ '2' ] ( )
2. 函数嵌套
2.1 嵌套调用
在函数中调用其它函数 .
def func1 ( ) : print ( 'form func1' ) def func2 ( ) : func1( ) print ( 'form func2' ) func2( )
2.2 嵌套死循环
两个函数体内互相调用函数 , 默认只有 1000 层嵌套 , 可以设置源码修改默认嵌套层数 , 超出就报错 :
英 : RecursionError : maximum recursion depth exceeded .
中 : 递归错误:超过了最大递归深度 .
def func1 ( ) : func2( ) def func2 ( ) : func1( )
func2( )
2.3 函数嵌套定义
函数嵌套定义 : 一个函数里用def语句来创建其它的函数的情况 .
目的 : 将复杂的功能全部隐藏 , 暴露一个接口 , 供操作者使用 ,
操作者不需要明白内部的代码是干什么的 , 只需要知道接口的功能 , 和使用方法即可 .
def all_func ( choices) : def add_staff ( ) : print ( '添加员工' ) def find_only ( ) : print ( '查询员工' ) def modify_salary ( ) : print ( '修改薪资' ) def all_staff ( ) : print ( '所有信息' ) def del_staff ( ) : print ( '删除员工' ) func_dic = { '1' : add_staff, '2' : find_only, '3' : modify_salary, '4' : all_staff, '5' : del_staff, } if choices in func_dic: func_dic[ choices] ( ) else : print ( '功能为开放!' ) while True : print ( """1. 添加员工2. 查询员工3. 修改薪资4. 所有信息5. 删除员工""" ) choice = input ( '请输入编号>>>:' ) all_func( choice)
3. 闭包函数
闭包函数 = 函数对象 + 函数嵌套定义 + 名称空间与作用域 .
闭包函数满足以下两个条件 :
* 1. 闭函数 : 定义在函数内部的函数 , 闭包函数是一种为函数传参的方案 .
* 2. 包函数 : 内部局部函数引用了外层局部函数的名称 .
3.1 直接传参
def func ( x, y) : print ( x, y) func( 1 , 2 )
3.2 闭包函数传参
def func1 ( ) : x = 1 y = 2 def func2 ( ) : print ( x, y) return func2func = func1( )
func( )
def func1 ( x, y) : def func2 ( ) : print ( x, y) return func2func = func1( 1 , 2 )
func( )
4. 递归函数
递归函数 : 在运行过程中直接或间接的调用自己 , 一种基于函数实现循环 .
默认嵌套 1000 层 , 超出报错 , 可以设置参数修改嵌套层次 , 某些电脑可能只能达到 99 ?层 .
递归是要有一定条件的 :
* 1. 每次递推之后复杂度相较于上一次一定要有所下降 .
* 2. 必须要能回溯 . 递归分两步 :
* 1. 递推 : 一层层往下推导结果 , 递推满足某个条件后 , 开始回溯 .
* 2. 回溯 : 依据最后的结果回溯得到最初问题的答案 .
4.1 示例1
推导第一个个小孩子的年龄 :
现在有五个小朋友 : 1 2 3 4 5 递推总次数 count = 5
第一个小朋友说比第二个小朋友大 2 岁 ↓ count - 1 + 2 ↑
第二个小朋友说比第三个小朋友大 2 岁 ↓ count - 1 + 2 ↑
第三个小朋友说比第四个小朋友大 2 岁 ↓ count - 1 + 2 ↑
第四个小朋友说比第五个小朋友大 2 岁 ↓ count - 1 + 2 ↑
第五个小朋友 18 岁 ↓ count = 0 return 18 ↑ 回溯
def get_age ( count) : count -= 1 if count == 0 : return 18 return get_age( count) + 2 print ( get_age( 5 ) )
def get_age ( count) : if count == 1 : return 18 return get_age( count - 1 ) + 2 print ( get_age( 5 ) )
4.2 示例2
打印出列表中每一个整型元素 .
list1 = [ 1 , [ 2 , [ 3 , [ 4 , [ 5 , [ 6 , [ 7 , [ 8 , [ 9 , [ 10 , [ 11 , [ 12 , [ 13 , [ 14 , ] ] ] ] ] ] ] ] ] ] ] ] ] ]
list1 = [ 1 , [ 2 , [ 3 , [ 4 , [ 5 , [ 6 , [ 7 , [ 8 , [ 9 , [ 10 , [ 11 , [ 12 , [ 13 , [ 14 , ] ] ] ] ] ] ] ] ] ] ] ] ] ] def print_element ( l1) : for i in l1: if type ( i) == int : print ( i) else : print_element( i) print_element( list1)
4.3 示例3
算法 : 解决问题的最高效方式 .
使用递归二分法快速找出序列序列的某个值 . 查找的元素就在数据集的头尾那么该算法不是很高效 . list1 = [ 11 , 23 , 43 , 57 , 68 , 76 , 81 , 99 , 123 , 321 , 432 , 567 , 666 , 712 , 899 , 999 , 1111 ]
将列表从中间一分为二 , 判断中间的值 , 比查找的值大还是小 .
在每次的二分之一基础上筛选掉一半的值 , 找到最后 , 要么存在要么不存在 .
l1 = [ 11 , 23 , 43 , 57 , 68 , 76 , 81 , 99 , 123 , 321 , 432 , 567 , 666 , 712 , 899 , 999 , 1111 ]
num = 23
def find_num ( list1, num) : if not list1: print ( '没有这个数据' ) return average = len ( list1) // 2 if list1[ average] < num: r_list = list1[ average + 1 : ] find_num( r_list, num) elif list1[ average] > num: l_list = list1[ : average] find_num( l_list, num) else : print ( '找到了' ) return find_num( l1, num)
l1 = [ 11 , 23 , 43 , 57 , 68 , 76 , 81 , 99 , 123 , 321 , 432 , 567 , 666 , 712 , 899 , 999 , 1111 ] def find_num ( list1, num) : if len ( list1) == 0 : print ( '查找的数字不存在!' ) return middle = len ( list1) // 2 print ( middle, list1[ middle] , num) if num < list1[ middle] : list1 = list1[ 0 : middle] find_num( list1, num) elif list1[ middle] < num: list1 = list1[ middle + 1 : ] find_num( list1, num) else : print ( '找到了' ) return input_num = int ( input ( '输入查找的数字>>>:' ) . strip( ) )
find_num( l1, input_num)
5. 匿名函数
匿名函数 : 指没有名字的函数 , 通常只使用一次 , 在需要一个函数 , 但是又不想思考起名字时使用 .
一般不会单独使用 , 都是配合其他函数一起使用 .
格式 : lambda 形参 : 计算返回值的表达式
返回形参处理的结果 .
print ( ( lambda x: x ** 2 ) ( 2 ) )
为匿名函数起名字 , 会提示不规范 :
英 : PEP8 : E731 do not assign a lambda expression , use a def .
中 : PEP8 : E731不指定lambda表达式,请使用def .
func = lambda x: x ** 2
res = func( 2 )
print ( res)