美文网首页python基础
14.python装饰器进阶之参数与返回值

14.python装饰器进阶之参数与返回值

作者: 花间派I风月 | 来源:发表于2019-01-15 21:20 被阅读1次

    一、带一个参数的装饰器

    • 上一节我们讨论的装饰器都是装饰不带参数的函数,现在要装饰一个带参数的函数怎么办呢?
    def timer(func):
        def inner(a): # 参数a
            start = time.time()
            func(a)
            print(time.time() - start)
        return inner
    
    @timer
    def func1(a):
        print(a)
    
    func1(1)
    

    二、带多个参数的装饰器

    • 其实装饰带参的函数并不是什么难事,但假如你有两个函数,需要传递的参数不一样呢?
    import time
    def timer(func):
        def inner(*args,**kwargs): # 无论多少参数都能解决
            start = time.time()
            re = func(*args,**kwargs)
            print(time.time() - start)
            return re
        return inner
    
    @timer   #==> func1 = timer(func1)
    def func1(a,b):
        print('in func1')
    
    @timer   #==> func2 = timer(func2)
    def func2(a):
        print('in func2 and get a:%s'%(a))
        return 'fun2 over'
    
    func1('aaaaaa','bbbbbb')
    print(func2('aaaaaa'))
    

    三、有返回值的装饰器

    • 现在参数的问题已经完美的解决了,可是如果你的函数是有返回值的呢?
    import time
    def timer(func):
        def inner(*args,**kwargs):
            start = time.time()
            re = func(*args,**kwargs)
            print(time.time() - start)
            return re  # 返回值
        return inner
    
    @timer   #==> func2 = timer(func2)
    def func2(a):
        print('in func2 and get a:%s'%(a))
        return 'fun2 over'
    
    func2('aaaaaa')
    print(func2('aaaaaa'))
    

    四、functools wraps

    • 刚刚那个装饰器已经非常完美了,但是正常我们情况下查看函数的一些信息的方法在此处都会失效

    查看函数信息的方式

    def index():
        '''这是一个主页信息'''
        print('from index')
    
    print(index.__doc__)    #查看函数注释的方法
    print(index.__name__)   #查看函数名的方法
    
    • 为了不让函数信息失效,我们还要在装饰器上加上一点来完善它:
    from functools import wraps
    
    def deco(func):
        @wraps(func) #加在最内层函数正上方
        def wrapper(*args,**kwargs):
            return func(*args,**kwargs)
        return wrapper
    
    @deco
    def index():
        '''哈哈哈哈'''
        print('from index')
    
    print(index.__doc__)
    print(index.__name__)
    

    五、 开放封闭原则

    1.对扩展是开放的
      为什么要对扩展开放呢?
      我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
    2.对修改是封闭的
      为什么要对修改封闭呢?
      就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。
    装饰器完美的遵循了这个开放封闭原则。

    相关文章

      网友评论

        本文标题:14.python装饰器进阶之参数与返回值

        本文链接:https://www.haomeiwen.com/subject/cdlrdqtx.html