前言:本文为小编自主学习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 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
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()
如有哪些地方写错,欢迎纠正



