一、闭包
1、闭包的语法要求
1. 发生函数嵌套
2. 内层函数使用到外层函数的参数
3. 外层函数返回内层函数的函数名
简单例子:
def func_out(data): def func_in(): print(data) return func_in a = func_out("123") a()
2、 闭包的作用
闭包可以保存外部函数内的变量,不会随着外部函数调用完而销毁。
由于闭包引用了外部函数的变量,则外部函数的变量没有及时释放,消耗内存。
二、装饰器
装饰器:在不修改函数的原有代码的前提下 给函数增加新的功能
- 装饰器本质上就是一个闭包函数,它可以对已有函数进行额外的功能扩展。
- 装饰器的语法格式:
# 装饰器 # def decorator(fn): # fn:被装饰的目标函数. # def inner(): # '''执行函数之前''' # fn() # 执行被装饰的目标函数 # '''执行函数之后''' # return inner
- 装饰器的语法糖用法: @装饰器名称,同样可以完成对已有函数的装饰操作。
1、装饰器的使用场景
- 函数执行时间的统计
- 输出日志信息
""" 时间阻塞:参数的单位为秒 time.time(10) 获取当前时间 """ import time def func_out(func): def func_in(): start = time.time() func() end = time.time() print(end - start) return func_in() @func_out def my_func(): for i in range(10000000): pass # my_func()
2、装饰有返回值的函数的装饰器
# 1. my_test() ==> func_in() # 2. func() ==> 原始的my_test def func_out(func): def func_in(): # ret就接受到了func的返回值 就相当于就收到了原始的my_test的返回值 ret = func() return ret # return func() return func_in @func_out def my_test(): return 10 a = my_test() print(a)
3、装饰有参数的函数
def func_out(func): def func_in(num1): func(num1) return func_in @func_out def my_func(num1): print(num1) # my_func() ==> func_in() # func() ==> 原始的my_func my_func(10)
- 使用带有参数的装饰器,其实是在装饰器外面又包裹了一个函数,使用该函数接收参数,返回是装饰器,因为 @ 符号需要配合装饰器实例使用
4、通用装饰器
def func_out(func): def func_in(*args): # args ==> (10,20,30) # *args ==> 10,20, # func(*args) ==> func(10,20,30) func(*args) return func_in @func_out def my_func(num1, num2, num3): print(num1) print(num2) print(num3) # my_func() ==> func_in() # func() ==> 原始的my_func my_func(10, 20, 30) # func_in(10,20,30) # args会以元组的形式存储单值参数 def my_func(*args): print(args) print(*args) my_func(10, 20, 30)
通用装饰器的语法格式:
# 通用装饰器 def logging(fn): def inner(*args, **kwargs): print("--正在努力计算--") result = fn(*args, **kwargs) return result return inner