装饰器

作者: 马梦里 | 来源:发表于2018-01-24 21:02 被阅读0次

    https://zhuanlan.zhihu.com/p/21696291
    https://www.zhihu.com/search?type=content&q=python%20%E8%A3%85%E9%A5%B0%E5%99%A8

    一、装饰器

    装饰器:装饰器实质上是一个函数,它把一个函数作为输入(参数)并且返回相同的函数,在这中间执行了其他的代码。其实就是闭包概念的深化。装饰器就是为已经存在的函数提供额外的功能

    def document_it(func):
        def new_function(*args, **kwargs):
            print('Running function:', func.__name__)
            print('Positional arguments:', args)
            print('Keyword arguments:', kwargs)
            result = func(*args, **kwargs)
            print('document_it Result:', result)
            return result
        return new_function
    

    这里定义了一个装饰器,往函数 document_it 传入一个函数 func,然后在document_it 里定义一个 new_function 函数,该函数一方面有其自己的逻辑,另一方面也撩了撩 func:result = func(*args, **kwargs),请记住,这里是确实调用了 func。最后,将整个 new_function 返回给外部了,这个 new_function 从模糊概念上来讲,是个闭包,如“预备知识”里讲的,它不是该函数执行结果

    def use_logging(func):
    
        def wrapper(*args, **kwargs):
            logging.warn("%s is running" % func.__name__)
            return func(*args)
        return wrapper
    
    @use_logging
    def foo():
        print("i am foo")
    
    @use_logging
    def bar():
        print("i am bar")
    

    最后返回的就是目标函数,通过位置参数可以根据目标函数实现多元传参;

    带参数的装饰器:也就是在外层又包裹了一个带参数的函数,最终都是返回目标函数:

    def use_logging(level):
        def decorator(func):
            def wrapper(*args, **kwargs):
                if level == "warn":
                    logging.warn("%s is running" % func.__name__)
                return func(*args)
            return wrapper
    
        return decorator
    
    @use_logging(level="warn")
    def foo(name='foo'):
        print("i am %s" % name)
    

    有多个装饰器时,从最靠近目标函数的装饰器开始执行:

    @a
    @b
    @c
    def f ():
    
    等效于
    
    f = a(b(c(f)))
    

    相关文章

      网友评论

          本文标题:装饰器

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