文章目录
一、递归
1.1 什么是递归?
-
所谓递归就是自己调用自己。
1.2 递归的原理及作用
-
递归的原理:
- 通过直接或者间接的形式去调用函数本身
-
递归的作用:
- 重复的调用函数本身,用来实现某些功能或者计算出某些数值,通常用在算法上面。
1.3 递归的分类
-
递归分为两种:
-
- 直接递归:函数自身调用自己。
-
- 间接递归:A函数调用B函数,B函数调用C函数,C函数再调用A函数。
-
1.4 在使用递归时的注意事项
-
递归一定要有条件限定,保证递归能够停止下来,否则会形成死循环并发生栈内存溢出。
-
递归中虽然限定了停止下来的条件,但是递归次数不能太多,否则也会发生栈内存溢出。
1.5 递归的使用
-
计算x开始到10内的和
-
def text(i): if i == 10: return 10 else: print(i) return i + text(i + 1) r = text(1) print("最终结果: "+str(r))
- 运行结果:
- 运行结果:
-
二、匿名函数
-
什么是匿名函数: 就是没有名字的函数。
-
匿名函数的使用场景: 用于仅仅临时使用一次的场景,没有重复使用的需求。
-
匿名函数的使用场景: 用于仅仅临时使用一次的场景,没有重复使用的需求。
-
匿名函数的语法: almbda +参数+冒号+函数体代码(表达式或者函数)
-
代码示例:
-
#比较以下薪资求薪资最高的那个人名 即比较多是value 但取的结果是key salarics={ 'xiaolong3':300000, 'xiaolong2':3000, 'long1':1000, } # 使用 max min sorted 默认比较是key值 返回也是key # 如何比较的 一个字母一个字母比较转码大小 # print(max(salarics)) # 这个函数需要获得字典的value 这样才会比较value def func(name): return salarics[name] # 比较func的返回值 也就是salaries的value值 但是还是返回key max的返回值是key # todo:key是sorted的一个形参,可以根据这个值来进行排序 print(max(salarics,key=func)) # 注意这个是可以不用写括号的 # 转化成匿名函数 print(max(salarics,key = lambda name:salarics[name])) # name:salarics[name] 取得是这个字典值 # 求最小值 print(min(salarics,key = lambda name:salarics[name])) # 但是我们要比较薪资 返回的要求是人名 # 薪资反序 print(sorted(salarics,key=lambda name:salarics[name],reverse=True))
- 运行结果:
- 运行结果:
-
三、闭包函数
-
什么是闭包函数: 在函数中定义的函数。
包指的是:该内部的函数名字在外部被引用
-
代码示例:
-
def outer(): # 没有调用outer() 但是创造了outer这个函数 # 1 只检测函数体的语法(工厂合不合格),不执行函数体代码(不使用工厂) print("外面的函数正在运行") def inner(): print("里面的函数正在运行") # 3 返回inner函数的内存地址 想像成inner工厂的一把钥匙 由outer的物流return # 3.1但需要注意的是 这个不要写括号 我要的是返回这个函数而不是调用 return inner # 2 执行了outer这个函数体代码,inner定义了 inner = outer()#4 得到了里面的inner钥匙 取名字inner 包子肉拿出来 print(inner) # 这里输出的是 inner的内存地址 # 5 里面的inner钥匙加括号运行 inner这个函数 inner() # 外围函数和闭包函数一起使用 但不规范 outer()()
- 运行结果:
- 运行结果:
-
3.1 闭包函数和正常函数的使用区别
-
正常函数
-
def func(x,y): print(x,y) # 每次都是传入同样的参数 func(3,2) func(3,2)
-
-
闭包函数
-
def outer(x,y): def func(): print(x+y) return func # 每次都是传入同样的参数 func = outer(3,2) # 为什么可以不写参数就可以获得呢 就相当于配料渗透到包子肉func函数地址里面去了 func()
-
四、装饰器(相当于 Java 中的面向切面编程)
4.1 装饰器概述
-
装饰器概述:
装饰器本身也是一个函数,是一个特殊的闭包函数。
装饰器的使用符合了面向对象编程的开放封闭原则。
-
装饰器的作用:
装饰器是给现有的模块增添新的小功能,可以对原函数进行功能扩展,而且还不需要修改原函数的内容,也不需要修改原函数的调用。-
在编程角度看,相当于Java中的面向切面编程,主要作用是在原本的功能上新增功能。
-
在测试角度上看,编写自动化测试脚本更加便捷。
-
4.2 装饰器的使用
-
import time def baiyu(): print("我在学习python") time.sleep(2) def count_time(func): def wrapper(): t1 = time.time() func() print("执行时间为:", time.time() - t1) return wrapper if __name__ == '__main__': baiyu = count_time(baiyu) # 因为装饰器 count_time(baiyu) 返回的时函数对象 wrapper,这条语句相当于 baiyu = wrapper baiyu() # 执行baiyu()就相当于执行wrapper()
- 运行结果:
- 运行结果:
-
这里的count_time是一个装饰器,装饰器函数里面定义一个wrapper函数,把func这个函数当作参数传入,函数实现的功能是把func包裹起来,并且返回wrapper函数。wrapper函数体就是要实现装饰器的内容。需要注意的是,装饰器的返回值需要是装饰器内部的函数。
4.3 简化装饰器(装饰器的语法糖@)
-
被装饰的函数放装饰器后面
-
装饰器定义好直接用@+装饰器名字叫可以给被装饰函数进行装饰
-
代码示例:
-
import time def count_time(func): def wrapper(): t1 = time.time() func() print("执行时间为:", time.time() - t1) return wrapper @count_time def baiyu(): print("我在学习python") time.sleep(2) if __name__ == '__main__': baiyu()
-
-