zoukankan      html  css  js  c++  java
  • python 装饰器

    1 函数装饰器

    构成:外部函数传入被装饰函数名,内部函数返回装饰函数名
    特点:不修改函数的调用方式,不修改函数的代码
    作用:在不对函数做任何修改的情况下增加额外的功能
    例如:缓存装饰器,权限验证装饰器,日志装饰器,路由装饰器,异常处理装饰器,错误重试装饰器,计时装饰器等
    函数装饰器装饰函数
    import time
    def timmer(func):
        def wrapper(*args,**kwargs):
            start_time = time.time()
            res=func(*args,**kwargs)  #如果被装饰函数有返回值,那么用res接收并return
            stop_time=time.time()
            print('run time is %s' %(stop_time-start_time))
            return res  
        return wrapper
    @timmer
    def add(a,b):
        return a+b
    print(add(1,2))
    print(add.__name__) #返回wrapper,被装饰的函数已经不再是它本身了 add=timmer(add),timmer方法返回的就是wrapper函数

    函数装饰器装饰类

    def Single(cls):
        clses = {}
    
        def single(*args, **kwargs):
            if cls not in clses:
                clses[cls] = cls(*args, **kwargs)
            return clses[cls]
        return single
    
    @Single
    class Food:
        def __init__(self,name):
            self.name = name
    
    a = Food('红薯') 
    b = Food('萝卜')
    print(a==b)# True
    print(a is b)# True
    print(Food.__name__)#single,原理同上

    函数装饰器的执行过程,我们修改一下示例1 。

    def timmer(func):
        print('外部函数 功能1')
        def wrapper(*args,**kwargs):
            print('内部函数 功能1')
            res=func(*args,**kwargs)
            print('内部函数 功能2')
            return res
        print('外部函数 功能2')
        return wrapper
    @timmer
    def add(a,b):
        return a+b
    #直接运行代码,结果:

    外部函数 功能1
    外部函数 功能2   可以看出在我们没有调用add方法的时候print已经生效了,这更说明被装饰的函数已经不再是他本身了

    add(2,3)

    外部函数 功能1
    外部函数 功能2
    内部函数 功能1
    内部函数 功能2   综合两个结果可以看出是先执行外部函数,返回内部函数wrapper,然后执行wrapper

    再看一个例子:

    def timmerA(func):
        print('A外部函数 功能1')
        def wrapperA(*args,**kwargs):
            print('A内部函数 功能1')
            res=func(*args,**kwargs)
            print('A内部函数 功能2')
            return res
        print('A外部函数 功能2')
        return wrapperA
    def timmerB(func):
        print('B外部函数 功能1')
        def wrapperB(*args,**kwargs):
            print('B内部函数 功能1')
            res=func(*args,**kwargs)
            print('B内部函数 功能2')
            return res
        print('B外部函数 功能2')
        return wrapperB
    @timmerB
    @timmerA
    def add(a,b):
        return a+b
    print(add(1,2))

    结果如下:

    A外部函数 功能1
    A外部函数 功能2  #先运行A装饰器外部函数
    B外部函数 功能1  #然后运行B装饰器外部函数
    B外部函数 功能2  
    B内部函数 功能1  #此时根据我们上个示例,应该运行被装饰函数,此时 add = wrapperB(wrapperA(add)) 这样应该就比较好理解了
    A内部函数 功能1  
    A内部函数 功能2
    B内部函数 功能2

    2 类装饰器

    类装饰器主要是通过类的__call__方法来实现的

    类装饰器装饰函数

    class Foo(object):
        def __init__(self, func):
            self._func = func
          
    def __call__(self): print('class decorator runing') self._func() print('class decorator ending') @Foo def bar(): print('bar') bar() print(bar.__name__) #报错,'Foo' object has no attribute '__name__'
    #举个例子
    class A:
    def __init__(self):
    pass
    a = A()
    print(a.__name__) # A instance has no attribute '__name__'

    类装饰器装饰类

    class Foo(object):
        def __init__(self, cls):
            self.cls = cls
    
        def __call__(self,name):
            s = self.cls(name)
            s.color = '红色'
            return s
    
    @Foo
    class Food:
        def __init__(self,name):
            self.name = name
    
    a = Food('红薯')
    print(a.name)
    print(a.color)
    print(Food.__name__)
  • 相关阅读:
    .net解决跨域问题
    win7系统安装不了Visual Studio及sql server相关问题整理
    Visual Studio注释代码段快捷键
    实现文件下载,将后台返回的字节流转成下载链接
    表单中输入内容,搜索时,下面table中该列中包含关键字的高亮显示
    实现select联动效果,数据从后台获取
    vue的v-model指令
    SSM框架中,controller的action返回参数给vue.js
    vue路由实现多视图的单页应用
    关于vue的增删改查操作
  • 原文地址:https://www.cnblogs.com/tigerzhouv587/p/11310650.html
Copyright © 2011-2022 走看看