首页 > 其他分享 >装饰器详解

装饰器详解

时间:2022-09-22 15:35:23浏览次数:56  
标签:__ return 函数 hello 详解 func 装饰 def

一、闭包

了解装饰器前,首先要了解,什么是闭包。

闭包就是在一个函数中再定义一个函数,内部函数需要引用外部函数的参数,且外部函数的返回值是内部函数。

def outside(x):
    def inside(y):
        return x + y
    return inside

print(outside(1)(2))
-----------------------------
>>>3

如代码所示,outside返回一个内部函数inside,且inside函数引用了outside函数中的变量x,这就是闭包。

因为outside函数返回的是inside函数,所以outside(1)就相当于

def inside(y):
    return 1 + y

outside(1)(2)相当于
def inside(2):
    return 1 + 2

 

二、装饰器

1、装饰器

装饰器就是闭包的一种应用。他的作用就是在不改变函数代码的基础上上,为函数扩展一些新功能。

当一个函数需要添加这个新功能时,只需要在函数上方添加@name即可。

import time

def needTime(func):
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print(f"当前函数耗时:{end_time - start_time}s")

    return inner

@needTime
def demo():
    time.sleep(1)
    print("hello")

demo()
-------------------------------

hello
当前函数耗时:1.0144729614257812s

如上代码所示,不需要修改hello()函数,就能添加计算函数耗时的功能

 

2、带参数的装饰器

def logging(level):
    def outwrapper(func):
        def wrapper(*args, **kwargs):
            print("[{0}]: enter {1}()".format(level, func.__name__))
            return func(*args, **kwargs)
        return wrapper
    return outwrapper

@logging(level="INFO")
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[INFO]: enter hello()
>>>hello, good morning

我们可以这么理解上方代码:

@logging(level="INFO")可以看作为:hello = logging("INFO")(hello)

logging函数的返回值为outwrapper函数,则:

hello = outwrapper(hello)

而outwrapper返回的就是wrapper,所以:

hello = wrapper(*args,**kwargs)

 

3、类装饰器

类装饰器的本质就是通过类方法中的call魔术方法来实现

(1)不带参数的类装饰器

class logging(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("[DEBUG]: enter {}()".format(self.func.__name__))
        return self.func(*args, **kwargs)

@logging
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[DEBUG]: enter hello()
>>>hello, good morning

(2)带参数的类装饰器

class logging(object):
    def __init__(self, level):
        self.level = level

    def __call__(self, func):
        def wrapper(*args, **kwargs):
            print("[{0}]: enter {1}()".format(self.level, func.__name__))
            return func(*args, **kwargs)
        return wrapper

@logging(level="TEST")
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[TEST]: enter hello()
>>>hello, good morning

 

参考原文:https://zhuanlan.zhihu.com/p/87353829

标签:__,return,函数,hello,详解,func,装饰,def
From: https://www.cnblogs.com/gzwTestblog/p/16719277.html

相关文章

  • CyclicBarrier使用详解
    1.CyclicBarrier是什么?从字面上的意思可以知道,这个类的中文意思是“循环栅栏”。大概的意思就是一个可循环利用的屏障。它的作用就是会让所有线程都等待完成后才会继......
  • Mysql的explain详解
    使用mysql提供的explain命令来查询sql语句的执行计划,查看sql语句有没有使用上索引,有没有全表扫描等。expain出来的信息有12列,分别是,id,select_type,table,partitions,type,possi......
  • extern的使用详解(多文件编程)——C语言
    extern——关键字extern是C语言中的一个关键字,一般用在变量名前或函数名前,作用是用来说明“此变量/函数是在别处定义的,要在此处引用”,extern这个关键字大部分读者应该是在......
  • 缓存详解
    springBoot与缓存JSR107javaCaching五个核心接口:CachingProvider:管理CachemanagerCacheManager:定义了创建、配置、获取、管理控制多个CacheCache:类似map只被一个C......
  • 装饰者模式、深拷贝、泛型序列化解决Caffeine中的缓存一致性问题
    一、前言Caffeine是一个高性能的Java缓存库,底层数据存储采用ConcurrentHashMap优点:因为Caffeine面向JDK8,在jdk8中ConcurrentHashMap增加了红黑树,在hash冲突严重时也......
  • linux命令:chmod(常用方法详解)
     linuxchmod命令是在日常运维中比较常用的命令之一,对文件管理比较重要,如设置web目录时需设置特定的权限以保证服务器安全。提示:在写完shell脚本后,我们一般需要给这脚本设......
  • FCKEditor配置及功能实现详解.
    ​ 在之前在工作中遇到在富文本编辑器中粘贴图片不能展示的问题,于是各种网上扒拉,终于找到解决方案,在这里感谢一下知乎中众大神以及TheViper。通过知乎提供的思路找到粘......
  • 装饰器的多种实现方式
    一、基于函数实现1、嵌套函数代码实现:1fromfunctoolsimportwraps234defdecorator(param):5defwrapper(func):6@wraps(func......
  • Linux中的一些命令详解
    一、命令行格式1.1、何为命令? 在Linux操作系统中,凡是在字符操作界面中输入能够完成特定操作和任务的字符串都可以称为命令命令通常只代表实现某一类功能的程序的名称......
  • require.context()的用法详解
    require.context(directory,useSubdirectories,regExp)directory:表示检索的目录seSubdirectories:表示是否检索子文件夹regExp:匹配文件的正则表达式,一般是文件名例......