zoukankan      html  css  js  c++  java
  • python 装饰器(复杂一点的)

    装饰器就是为了在不改变函数代码的情况下为函数添加新的功能

    实例

    def note(func):
        "note function"
        print('note')
        def wrapper(x1,x2):
            "wrapper function"
            print(x1)
            print(x2)
            print('note something')
            # func(x1,x2)
            return func(x1,x2)
    
        return wrapper
    
    @note   #test=note(test)
    def test(a1,a2):
        "test function"
        print('I am test')
    
    
    test(3,5)  #note(test)()
    # print(test.__doc__)
    带参数的装饰器,在普通装饰器外边再套一个函数,实现可以传递额外参数
    import time
    def time_logger(flag=0):
        def show_time(func):
            def wrapper(*args,**kwargs):
                start_time=time.time()
                func(*args,**kwargs)
                end_time=time.time()
                print(end_time-start_time)
    
                if flag:
                    print('将这个操作记录到日志中')
            return wrapper
    
        return show_time
    @time_logger(1)
    def add(*args,**kwargs):
        time.sleep(1)
        sum=0
        for i in args:
            sum+=i
        print(sum)
    
    add(1,5,9)

    多层装饰器
    装饰器函数的执行顺序分为(被装饰函数)定义阶段和(被装饰函数)执行阶段
    在被装饰函数定义阶段,执行顺序是从最靠近函数的装饰器开始,自内而外执行
    在被装饰函数执行阶段,执行顺序由外而内
    需要注意的是,装饰器函数在被装饰器函数定义好的时候就立即执行了
    def A(fn):
        print('执行A')
        def inner1():
            print('开始执行inner1')
            fn()
            print('结束inner1')
        return inner1
    
    def B(fn):
        print('执行B')
        def inner2():
            print('开始执行inner2')
            fn()
            print('结束inner2')
        return inner2
    
    @A
    @B
    def hello():   #A(B(hello))
        print('hello')
    
    hello()

    执行B
    执行A
    开始执行inner1
    开始执行inner2
    hello
    结束inner2
    结束inner1

    类装饰器
    需要依靠类内部的__call__方法
    import time
    class Foo:
        def __init__(self,func):
            self.func=func
        def __call__(self, *args, **kwargs):
            start_time=time.time()
            self.func()
            end_time=time.time()
            print(end_time-start_time)
    @Foo    #bar=Foo(bar)
    def bar():
        print('bar')
        time.sleep(1)
    bar()   #Foo(bar)()
    functools.wraps,用于解决装饰器的副作用
    import functools
    def foo():
        print('hello foo')
    print(foo.__name__)
    def C(func):
        # @functools.wraps(func)    能把原函数的原信息拷贝到装饰器函数中,解决装饰器的副作用
        def inner(*args,**kwargs):
            print(func.__name__+'!!!!!')
            return func(*args,**kwargs)
        return inner
    @C
    def cal(x):
        return x+x*x
    print(cal(2))
    print(cal.__name__)
    # foo
    # cal!!!!!
    # 6
    # inner  这时的cal.__name__变成装饰器内部函数的名称了


    写出漂亮的博客就是为了以后看着更方便的。
  • 相关阅读:
    读书笔记——数据结构(1)开篇吐槽
    问题解决——产生未引用参数的警告
    移植对话框资源
    问题解决——XP线程池找不到QueueUserWorkItem
    SD 笔记01
    css3 笔记 背景
    Css3 笔记 动画 和定位属性
    小程序笔记
    C# E店宝格格家接口对接
    JS:onmouseover 、onmouseout
  • 原文地址:https://www.cnblogs.com/zhaowei5/p/10230038.html
Copyright © 2011-2022 走看看