装饰器是一种特殊的函数,它可以接受一个函数作为参数,并返回一个新的函数。装饰器可以用来修改或增强函数的行为,而不需要修改函数本身的代码。在Python中,装饰器通常用于实现AOP(面向切面编程),例如日志记录、性能分析、缓存等。装饰器的语法使用@符号,将装饰器函数放在被装饰函数的定义之前学过设计模式的朋友都知道,设计模式的结构型模式中也有一个叫装饰器模式,那这个和Python中的装饰器有什么不同呢?
设计模式中的装饰器是一种结构型模式,它可以在不改变原对象的情况下,为对象添加额外的功能。装饰器模式通常用于在运行时动态地为对象添加功能,而不是在编译时静态地为对象添加功能。装饰器模式通常涉及到多个对象之间的协作,而不是单个函数或对象。因此,Python中的装饰器和设计模式中的装饰器虽然名称相同,但是它们的实现方式和应用场景有很大的不同。
闭包是指一个函数和它所在的环境变量的组合,即在函数内部定义的函数可以访问外部函数的变量和参数,即使外部函数已经返回。闭包可以用来实现函数式编程中的柯里化、惰性求值、函数组合等高级特性。看着上面的文字,是不是感觉有点抽象。我说一说我对闭包的理解
闭包是由外部函数和内部函数,内部函数引用到了外部函数定义的变量,外部函数的返回值是内部函数的函数名。对于这样的函数,我们就称为闭包。好像也有点抽象,我们来看一断代码,就能够理解上面的话了。
当使用@装饰器时,会自动执行 闭包中的外部函数内容。这个可以自行验证。当使用@装饰器时,Python解释器为我们做了什么?
当使用@装饰器时,Python解释器会将被装饰的函数作为参数传递给装饰器函数,并将其返回值作为新的函数对象替换原来的函数对象。这样,每次调用被装饰的函数时,实际上是调用了装饰器函数返回的新函数对象。通过下面的函数,可以得知,inner和test函数指向的是同一个内存地址。
Python 装饰器 @ 实际上是一种语法糖,它可以让我们在不改变原函数代码的情况下,对函数进行扩展或修改。当我们使用 @ 装饰器时,实际上是将被装饰函数作为参数传递给装饰器函数,然后将装饰器函数的返回值赋值给原函数名。因此,@ 装饰器并不会进行内存拷贝。
Python装饰器在装饰函数时,会将原函数的函数名、文档字符串、参数列表等属性复制到装饰器函数中,但是装饰器函数并不会复制原函数的所有属性。例如,原函数的name属性、doc属性、module属性等都不会被复制到装饰器函数中。为了避免这种情况,可以使用functools库中的wraps装饰器来保留原来函数对象的属性。wraps装饰器可以将原来函数对象的属性复制到新的函数对象中,从而避免属性丢失的问题。
ProcessTime 中的__call__ 中的代码并不会执行完后再去执行 ProcessTime2 中的__call__,而是在调用 ret = self.func(*args, **kwargs) 方法后,就回去执行 ProcessTime2 中的__call__的代码。4.3 类装饰器存在的问题
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) | Powered by Discuz! X3.4 |