Python 装饰器

来源:互联网 发布:淘宝助理创建宝贝教程 编辑:程序博客网 时间:2024/05/20 21:57
  • 软件开发的一条原则是开放封闭原则:对扩展是开放的,对修改是封闭的。

装饰器的功能:在不修改被装饰对象源代码以及调用方式的前提下,为其添加新的功能

原则:1、不能修改源代码    2、不修改调用方法

目标:添加新功能

  • 最简单的装饰器,举个栗子:
    定义一个简单的函数 def = web(),其执行效果是停顿,然后的输出一条信息 ,现在我们为其增加一个功能,让web函数在执行完毕后,显示其运行时间。
    import timeimport random# 装饰器:def timer(func):     # 将函数作为参数传入    # func = web    def wrapper():        start = time.time()        func()  # web()        end = time.time()        print('running time is %s' % (end-start))    return wrapper#被装饰函数:@timerdef web():    time.sleep(random.randrange(1,2))    print('welcome to this web!')web = timer(web)    # web = wrapperweb()   # wrapper()  运行结果如下:welcome to this web!running time is 1.0000369548797607
  • 装饰器的语法:在被装饰对象的正上方@装饰名,将对象作为参数传个装饰器函数,运行装饰器函数。
  • 有多个装饰器的情况,比如再为上面的web函数添加登录认证功能:
    import timeimport random# 装饰器:def timer(func):    # func = web    def wrapper():  #        start = time.time()        func()  # web()        end = time.time()        print('running time is %s' % (end-start))    return wrapperdef auth(func):    def deco():        while True:            name = input('enter your name: ').strip()            pwd = input('password: ').strip()            if not name or not pwd: continue            if name == 'ayhan' and pwd == '123':                print('login ok')                func()                break            else:                print('login error')    return deco#被装饰函数:@auth@timer    # def web():    time.sleep(random.randrange(1,2))    print('welcome to this web!')web()  #执行被装饰后的函数,结果如下:enter your name: ayhanpassword: 123login okwelcome to this web!running time is 5.938760995864868
    从上面的例子可以看到,有多个装饰器时,从上往下运行。
  • 装饰器可以装饰多个对象,有些对象需要传入参数,有些对象需要传入参数,而有些不需要,有些需要返回值,有些不需要,解决方案如下:
    import timeimport random# 装饰器:def timer(func):     # 将函数作为参数传入    # func = web    def wrapper(*args,**kwargs):  # 传入任意参数        start = time.time()        res = func()  # web()   # 函数返回值赋给res        end = time.time()        print('running time is %s' % (end-start))        return res   # 返回res    return wrapper#被装饰函数:@timerdef web():    time.sleep(random.randrange(1,2))    print('welcome to this web!')@timerdef home(name):    time.sleep(random.randrange(1,2))    print('welcome to home of %s' % name)    return 100
  • 查看函数注释文档:print(help(index)) 和 print(func.__doc__)
    如果是装饰过的函数,查看的装饰器内函数的文档。查看原始函数的文档方法如下:
    from functools import wraps
    把@wraps(func)放在装饰函数的上方

    另外,func._wrapped_() 查看原始函数的执行效果。
  • 有参装饰器:
    思路:如何给原来的装饰器传入参数----》使其成为闭包函数,在外面再包一层函数用来接收参数:


原创粉丝点击