python的装饰器

python的装饰器,第1张

概述引子:我以为我会了,看了看flask路由的源码,大概一看能看懂,仔细推敲发现还是理解的浅显,写篇博客压压惊吧。 代码:普通写法装饰器不传参数defwarp3(f):'''这个f是形参数哪怕你传个x,y,z它也是被装饰的函数有点像类方法中的第一个参数self'''print(f)

引子:

  我以为我会了,看了看flask路由的源码,大概一看能看懂,仔细推敲发现还是理解的浅显,写篇博客压压惊吧。

 

代码:

  普通写法 装饰器不传参数

def warp3(f):     ''' 这个f 是形参数 哪怕你传个 x,y,z 它也是被装饰的函数 有点像类方法中的 第一个参数self'''    print(f)    def inner(*args,**kwargs):        print("in warp3")        ret=f(*args,**kwargs)        return ret    return inner@warp3def func4(*args,**kwargs):    return 444func4 ====这个时候 func4 已经重新指向了装饰器中的 inner 不信打印下结果

  带参数的写法

test_dict={}def warp(rule,**options):    def inner(f):        print(13)        enpoint=options.pop("enpoint",None) or f.__name__        test_dict[enpoint]=f        return f    return inner@warp('uuuu')def func(*args,**kwargs):    return 1if __name__ == '__main__':    pass 即使没有调用func 这里其实已经执行了装饰器    装饰器本身也是个函数 @warp('uuuu')  这里等于执行了inner函数    # func()    # print(test_dict)

  对应的flask route部分源码

    def route(self, rule, **options):                print("route===>",rule,options)        def decorator(f):            print("route=decorator==>", f)            endpoint = options.pop("endpoint", None)            self.add_url_rule(rule, endpoint, f, **options)            return f        return decorator

      打印结果

route===> / {'methods': ['GET', 'POST'], 'endpoint': 'test_index'}route=decorator==> <function index at 0x7fb60dfac0d0>

  其实等同于 ret= decoator 然后 decoator又去装饰的 视图函数 

 

  其他写法:

def warp3(rule): 同样这里 rule 还是 形参    def inner(*args,**kwargs):        print("in warp3")        ret=rule(*args,**kwargs)        return ret    return inner@warp3def func4(*args,**kwargs):    return 444

  上述写法中并不会报错 因为rule 默认是 被装饰函数 ,并且下方也引用了,但是下方写法会报错

test_dict={}def warp(rule,**options):    print(12)    def inner(f):        print(13)        enpoint=options.pop("enpoint",None) or f.__name__        test_dict[enpoint]=f        return f    return inner@warp  # 本质 也是 函数 不加 () 不调用  下方在直接调用的时候 会报错 def func2(*args,**kwargs):    return 2if __name__ == '__main__':    func2()报错的原因是 在装饰器执行的时候rule 形参 就是 被装饰函数 实际返回的是innerinner需要 一个参数 f 也是形参 但是下方调用的时候没有传

   改下写法就不会报错

test_dict={}def warp(rule,**options):    print(12)    def inner(f):        print(13)        enpoint=options.pop("enpoint",None) or f.__name__        test_dict[enpoint]=f        return f    return inner@warpdef func2(*args,**kwargs):    return 2if __name__ == '__main__':    这里需要传一个 可调用对象 否则 装饰器中  f.__name__报错 程序中断    func2(lambda a:1) 

  正经写法推理

def warp2(f):    def inner(*args,**kwargs):        print("in warp2 ")        ret=f(*args,**kwargs)        return ret    return inner@warp2def func3(*args,**kwargs):    return func3.__name__if __name__ == '__main__':    # print(func3())1 装饰只接受了 被装饰函数 没有其他参数 这时候实际返回的是  inner2 func3() 调用的时候 实际上 是执行的inner 

  再次证明 装饰器第一个参数 是 被装饰函数

def warp5(args,**options):    print(args, options)    def inner(name):        print(args,options)        ret=args(name)        return ret    return inner@warp5def func5(name,**kwargs):    print(name)    return func5.__name__if __name__ == '__main__':   #print(func5('rrr'))1 同上 这里 装饰器没加括号 返回的依然是inner 虽然第一个参数是args 依然是形参数如果你传了 *args 。。。。2 同样又给inner传参数 name = ‘rrr’

  

总结:

  1 python的gc机制 引用归零 

      2 装饰器内参数的引用,以及使用时传参数的顺序

  3 装饰器本身就是个闭包函数

      4 多看框架源码 无论知识体系还是代码风格都是一种加强,并且不是一星半点

  

总结

以上是内存溢出为你收集整理的python的装饰器全部内容,希望文章能够帮你解决python的装饰器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/1186816.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存