装饰器

2018-01-24  本文已影响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)))
上一篇下一篇

猜你喜欢

热点阅读