目录
在python中有许多装饰器,那么我们怎么自己去实现装饰器的功能呢?
装饰器
在python中有许多装饰器,那么我们怎么自己去实现装饰器的功能呢?
首先要了解一些概念:如生命周期,闭包
生命周期
一个模块有模块的生命周期;一个类有类的生命周期;一个变量有变量的生命周期
闭包
闭包的条件(缺一不可)
1. 必须有一个内嵌函数 >= 1 2. 内函数必须引用外函数的变量 3. 外函数必须返回内函数
形成闭包之后,闭包函数会得到一个非空的 __closure__属性
# 闭包
# 变量的解析原则 LEGB
def outer(x):
a = 300
def inner():
print(f"两数之和为: {x + a}")
return inner
d = outer(10)
d()
print(d.__closure__)
---- result
两数之和为: 310
(<cell at 0x000001F8763B9A98: int object at 0x000001F876A9D2B0>, <cell at 0x000001F876899948: int object at 0x00007FFB30CC7D60>)
变量的解析原则 LEGB
L —— Local(function);函数内的名字空间 E —— Enclosing function locals;外部嵌套函数的名字空间(例如closure) G —— Global(module);函数定义所在模块(文件)的名字空间 B —— Builtin(Python);Python内置模块的名字空间
🍎🍺🍻
现在知道什么是闭包了,就来看看python装饰器
什么是python装饰器以及它的作用?
装饰器必须装饰的 具有 __callable __对象
装饰器是这样一种设计模式:如果一个类(函数)希望添加其他类(函数)的一些功能,而不希望通过继承或是直接修改源代码实现,那么可以使用装饰器模式 通俗的来说:在不改变函数或者类的源代码的基础上,添加额外功能 装饰器的本质就是闭包函数,不同之处就是需要传入一个 callable 对象
# 统计运行时间的装饰器
import time
def runtime(func):
def inner():
start = time.time()
func()
end = time.time()
print(f"函数执行花了{end - start}s")
return inner
@runtime # @装饰符 去使用装饰器
def func1():
time.sleep(2)
print("func1 .....")
func1()
----result
func1 .....
函数执行花了2.0011112689971924s
优化后的代码(保证代码的健壮性)
# 统计运行时间的装饰器
import time
def runtime(func):
print("this is runtime")
def inner(*args,**kwargs): # 让装饰器更加通用
start = time.time()
result = func(*args,**kwargs)
end = time.time()
print(f"函数执行花了{end - start}s")
return result
return inner
@runtime # func3 = runtime(func3)
def func3(a,b):
time.sleep(3)
print(f"func1 {a} + {b} = {a + b}")
return a + b
func3(2, 6)
result = func3(1, 3)
print(result)
-------------------------result
func1 2 + 6 = 8
函数执行花了3.0104315280914307s