python装饰器原理

目录

装饰器

在python中有许多装饰器,那么我们怎么自己去实现装饰器的功能呢?

 闭包的条件(缺一不可)

变量的解析原则 LEGB

什么是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
    

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python装饰器原理是利用了Python的函数式编程特性,将一个函数作为参数传入另一个函数,并且返回一个新的函数。这个新的函数可以执行原来的函数,并且在执行前后添加一些额外的功能。 其,functools是Python一个常用的工具库,提供了一些函数式编程的工具,包括partial函数和wraps函数。partial函数可以将一个函数的部分参数固定下来,返回一个新的函数,方便后续调用;wraps函数可以将一个函数的元信息(如函数名、文档字符串等)复制到另一个函数,避免装饰器对元信息造成的影响。 在使用装饰器的时候,可以借助functools.partial函数来实现带参数的装饰器,例如: ``` from functools import partial def repeat(num): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): for i in range(num): func(*args, **kwargs) return wrapper return decorator @repeat(num=3) def hello(): print("hello") # 输出:hello hello hello hello() ``` 在这个例子,repeat函数返回一个decorator函数,decorator函数接受一个func参数,返回一个wrapper函数。wrapper函数在执行原来的函数前后,重复执行num次。为了保留原来函数的元信息,使用了wraps函数来复制元信息。使用partial函数来给装饰器传递参数,实现了带参数的装饰器。 总之,Python装饰器原理和实现方式非常灵活,可以根据需求选择不同的实现方式,方便地实现各种功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值