1.闭包的简单示例
''' 闭包的形成条件: 1、必须有函数的嵌套(外部函数和内部函数) 2、调用外部函数 会返回内部函数 3、内部函数使用外部函数的变量(参数) ''' # 外部函数 def func_out(num1): # 内部函数 def func_inner(num2): # num2 = 5 print(num1 + num2) print("内部函数", func_inner) # 返回内部函数 return func_inner if __name__ == '__main__': # f = func_out() = func_inner f = func_out(4) print(f) # f(5) = func_out()(5) = func_inner(5) f(5) f(7)
2.闭包的使用
# 外部函数 def config_name(name): # name = Tom # 内部函数 def say_info(info): # info= "你今天吃什么" # 将外部函数的参数和内部函数的参数拼接 print(name + ":" + info) # 返回内部函数 return say_info if __name__ == '__main__': # t = config_name("Tom") = say_info t = config_name("Tom") # t("你今天吃什么")=config_name("Tom")("你今天吃什么")=say_info("你今天吃什么") t("你今天吃什么") j = config_name("jerry") j("我今天不饿") ''' 随堂练习 1.外部函数传名字,内部函数传健康码 使用闭包 得出结论 打印出 张三红码 需要被隔离 ''' def config_name(name): # name = Tom # 内部函数 def say_info(info): # info= "你今天吃什么" # 将外部函数的参数和内部函数的参数拼接 if int(info) == 1: print(name, "去送饭") elif int(info) == 2: print(name, "被送饭") elif int(info) == 3: print(name, "隔离") # 返回内部函数 return say_info if __name__ == '__main__': # t = config_name("Tom") = say_info t = config_name("张三") t(input("张三你的健康码")) f = config_name("李四") f(input("李四你的健康码")) a = config_name("王五") a(input("王五你的健康码"))
3.外部函数变量的修改
# 在内部函数修改外部函数 # 错误示范 def func_out(num1): # num = 1 def func_inner(num2): # num2 = 2 # 这样的修改 只是从新创建了一个变量 num1 = 10 print(num1 + num2) # num1 = 1 说明内部函数的修改没有生效 print("num1:", num1) func_inner(1) print("num1:", num1) return func_inner if __name__ == '__main__': # f = func_out(1)=func_inner f = func_out(1) f(2)
4.nolocal关键字
# 在内部函数修改外部函数 # 正确示范 def func_out(num1): # num = 1 def func_inner(num2): nonlocal num1 # 告诉解释器num1是外部函数的变量 # num2 = 2 # 这样的修改 只是从新创建了一个变量 num1 = 10 print("求和", num1 + num2) # num1 = 1 说明内部函数的修改没有生效 print("num1:", num1) # 1 func_inner(2) # num2 = 2 print("num1:", num1) # 10 return func_inner if __name__ == '__main__': func_out(1)
5.使用装饰器计算函数
""" 使用装饰计算func运行的总时间 """ import time def decorate(fn): # fn = func def inner(): # 时间戳 start = time.time() fn() end = time.time() print(f"程序运行的总时间是:{end - start}秒") return inner @decorate # 相当于func = decorate(func()) def func(): for i in range(100000): print(i) if __name__ == '__main__': # func被装饰之后的func func()
6.装饰器的代码示例
# 装饰器 # 登录验证 """ fn是函数本身 fu()函数的调用 装饰器的功能特点 1.不改变原有函数的代码 2.不改变原有函数的调用 3.给函数本身添加一些新的功能 """ def check(fn): # fn = comment def inner(): print("登录验证") # 发表评论 fn() return inner # 评论函数 def comment(): print("今天天真好...") if __name__ == '__main__': # comment = check(comment) = inner # comment是装饰之后的comment 括号里面的comment是没有被装饰的comment comment = check(comment) # comment() = check(comment)() = inner comment()
7.随堂练习
""" 随堂练习 1.有一个吃饭函数 使用装饰器给它添加一些功能 吃饭前洗手 吃饭后打刘鸡鸡 """ # 声明一个装饰器 def decorate(fn): # fn = eat def inner(): print("吃饭前洗手") fn() # fn() = eat() 这是eat是没有装饰的eat print("吃饭后打刘鸡鸡") return inner def eat(): print("吃饭") def sleep(): print("睡觉") if __name__ == '__main__': # eat = decorate(eat) = inner eat = decorate(eat) # eat() = decorate(eat)() = inner() eat() print("=================") # 装饰别的函数 每次都需要写这一行代码 sleep = decorate(sleep) sleep()
8.语法糖写法
# 声明一个装饰器 def decorate(fn): # fn = eat def inner(): print("吃饭前洗手") fn() # fn() = eat() 这是eat是没有装饰的eat print("拉臭臭") return inner # @decorate 相当于 eat = decorate(eat) @decorate def eat(): print("吃饭") # @decorate 相当于 sleep = decorate(eat) @decorate def sleep(): print("睡觉") if __name__ == '__main__': # eat = decorate(eat) = inner # eat = decorate(eat) # eat() = decorate(eat)() = inner() eat() sleep()
9.带有参数的装饰器
""" 日志打印 装饰器对传参 """ def logging(fn): # fn = sum_mun没有被装饰的sun_num def inner(num1, num2): # num1 = 1 num2 = 2 print("计算") fn(num1, num2) return inner # @logging 相当于sun_num = logging(sun_num) @logging def sum_num(a, b): print("求和:", a + b) if __name__ == '__main__': # sun_num(1, 2) = logging(sun_num)(1, 2) = inner(1, 2) sum_num(1, 2)
10.随堂练习
""" 随堂练习 1.评论函数 对评论函数进行装饰, 验证账号和密码的正确性 账号xmr123456 密码123456 评论之前实现账号登录成功 打印可以开始评论 使用装饰器完成上面的功能 """ def decorate(fn): # fn = comment def inner(ac, pw): # ac pw 是接收的账号 if ac == "xmr123456" and pw == "123456": print("密码正确开始评论") fn() else: print("账号或者密码错误") return inner @decorate def comment(): print("评论") if __name__ == '__main__': account = input("输入账号") password = input("输入密码") comment(account, password) # inner