• 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__)
  • 相关阅读:
    (Toolbar)Android中如何消除Toolbar左边的空白
    (TextView)Android中为TextView赋初始值
    (Edittext)Android中界面中有多个Edittext,如何默认让第二个获取焦点
    (警告)Android中报Custom view `×××` has setOnTouchListener called on it but does not override performClick警告
    (Toolbar)Android中app:showASAction的值及含义
    个人课程总结
    (list)关于list清空问题的解决
    Ubuntu hive 安装过程中遇到的一些问题
    学习进度——第十七周
    个人课程总结
  • 原文地址:https://www.cnblogs.com/tigerzhouv587/p/11310650.html
Copyright © 2020-2023  润新知