前言:本文为小编自主学习python的过程中的笔记和对应的练习应用 ,希望能帮助到大家,也希望大家能一起交流学习,如对你学习有帮助记得点赞加关注哦,每个星期小编都会更新一篇的。
目录
一、递归函数
递归特点
二、闭包
函数引用
闭包条件
闭包应用
回调函数
三、修饰器
装饰器的理解
装饰器的功能
语法糖
装饰器的应用
一、递归函数
如果一个函数在内部不调用其它的函数,而是自己本身的话,这个函数就是递归函数。
递归是一种编程思想:
- 在我们日常开发中,如果要遍历一个文件夹下面所有的文件,通常会使用递归来实现
- 在后续算法中,很多算法都离不开递归,例如:快速排序
- 函数内部自己调用自己
- 必须有出口
应用:用递归实现3以内的数字累加和
def sums_number(num): # sums_number(3) 3以内的数字累加和 # 出口 if num ==1: # 如果没有这个出口,无限次的调用函数 return 1 # 1以内的数字累加和 = 1 return num + sums_number(num-1) nums = sums_number(3) print(nums)二、闭包
- 引用就是变量指向数据存储空间的现象
def test1(): print("hello") print(id(test1)) # 3196428759688 test1指向函数地址 test1() ret = test1 # test1() ret() ret() # 函数引用(内存地址)
闭包的定义:如果一个内嵌函数访问外部嵌套函数作用域的变量,并返回这个函数,则这个函数就是闭包
闭包条件- 函数中嵌套一个函数
- 内层嵌套函数对外部作用域有一个非全局变量的引用
- 外层函数的返回值是内层函数的函数名
def outer(m): n = 10 def inner(): print(m+n) return inner() # 调用函数 outer(2)
这是简单的函数嵌套 。
def outer(m): n = 10 def inner(): print(m+n) return inner # 这里没加括号是返回函数名,而加了括号就是直接调用函数了 # 函数引用 函数名2 =函数名 函数名2() ot = outer(2) # inner 函数名 ot() # 调用函数 outer(2)() # outer(2) = inner 这行代码和上面ot()等效
这是简单的一个闭包。
闭包作用:保存局部信息不被销毁,保证数据的安全性。
闭包应用- 可以读取函数内部的变量
- 让这些变量的值始终保存在内存中
- 装饰器
def funa(sums): num = 1 # 局部变量 num+=sums print(num) for i in range(5): funa(3)
运行上面的代码发现会打印5次,并且结果都为4。这是因为num=1是局部变量,每次调用都被销毁重新赋值。如果想每次调用都能保存上一次的局部变量,那就需要闭包 *** 作。如:
def funa(sums): num=1 def outer(): # 1.嵌套函数 # 2.在内部函数里面有对外部函数的引用 nonlocal num # 声明num这个变量父级num num+=sums # num=num+sums print(num) # 3.在外部函数返回内部函数函数名 return outer fa = funa(3) # fa = outer for i in range(5): fa() # 闭包实现局部变量不被销毁
这次的结果就是我们想要的,为4,7,10,13,16。每次循环上一次的局部变量num成功被保留了
回调函数回调函数指的是通过函数参数传递到其他代码的,某一块可用执行代码的应用
def funa(fb): fb() # funb() print("这是funa函数") def funb(): print("这是funb函数") funa(funb) # 把函数作为参数传进去,在其他函数里面调用这个函数三、修饰器
装饰器:在不改变原被装饰的函数的源代码以及调用方式下,为其添加额外的功能
装饰器本质上就是一个闭包函数
开发封闭原则:
一个软件实体应当对扩展开放,则修改关闭。设计的目的便在于面对需求的改变而保持系统的相对稳定,从而使得系统可以很容易的从一个版本升级到另一个版本。
装饰器的理解- 实质: 是一个闭包函数
- 参数:是你要装饰的函数名(并非函数调用)
- 返回:是装饰完的函数名(也非函数调用)
- 作用:为已经存在的对象添加额外的功能
- 特点:不需要对对象做任何的代码上的变动
- 函数执行时间统计
- 可以用在框架的路由传参上
- 插入日志
- 事务处理
- 权限校验
- 缓存
def add(h1): # 装饰器 def outer(): h1() # 调用house1() print("戴森吹风机") return outer def house1(): print("三室一厅的房子") print("三星电视") print("三菱电机") ot = add(house1) ot()
一个简单的修饰器,在你的“小房子”里加个电器
语法糖装饰器的语法糖用法: @装饰器名称,同样可以完成对已有函数的装饰 *** 作。
@装饰器名称
被装饰的函数
# 语法糖 @装饰器名称 def add(h1): # 装饰器 def outer(): h1() # 调用house1() print("戴森吹风机") return outer @add # 装饰器名称 def house1(): # 被装饰函数 print("三室一厅的房子") print("三星电视") print("三菱电机") house1()
当有多个修饰器时调用顺序问题:比如在你的“小房子”里新增一个打扫函数,要求在添加吹风机之前先打扫,再添加吹风机...
def cleaner(h1): # 装饰器 def outer(): h1() # 调用house1() print("正在打扫...") return outer def add(h1): # 装饰器 def outer(): h1() # 调用house1() print("戴森吹风机") return outer @add # 装饰器名称 @cleaner def house1(): # 被装饰函数 print("三室一厅的房子") print("三星电视") print("三菱电机") house1() # 多个装饰器执行顺序:离被装饰函数越近的装饰器会先执行(就近原则) # 在添加吹风机之前先打扫装饰器的应用
# 编写一个装饰器,计算用户登录的执行时间 # 装饰函数:执行时间 被装饰函数:用户登录 """ 1.写一个用户登录函数 2.写计算时间的函数 time(内置模块) time.time() # 计算时间戳 当前时间-1970 即距离1970年的秒数 在登录之前拿时间戳 调用登录函数 在登录之后拿时间戳 3.使用装饰器调用函数 """ import time def timer(login): def logs(): stime = time.time() login() etime = time.time() print(f"用户登录时间为{etime-stime}s") return logs @timer def login(): name = input("请输入用户名:") pwd = input("请输入密码:") if name=="admin" and pwd=="123": print("登录成功") login()
如有哪些地方写错,欢迎纠正
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)