python decorator

2019-04-03  本文已影响0人  白菜的白v

实现一个log的decorator,使它既支持:

@log
def f():
    pass

也支持:

@log("ERROR")
def f():
    pass

实现:

from functools import wraps

def log(ft):
    if isinstance(ft, str):
        level = ft
        def wrapper(func):
            @wraps(func)
            def inner_wrapper(*args, **kwargs):
                print("Log[%s]: call %s()" % (level, func.__name__))
                c = func(*args, **kwargs)
                print("Log[%s]: end call %s()" % (level, func.__name__))
                return c
            return inner_wrapper
        return wrapper
    else:
        level = "INFO"
        @wraps(ft)
        def wrapper(*args, **kwargs):
            print("Log[%s]: call %s()" % (level, ft.__name__))
            c = ft(*args, **kwargs)
            print("Log[%s]: end call %s()" % (level, ft.__name__))
            return c
        return wrapper

使用log 装饰器装饰方法:

@log
def my_sum(*args):
    return sum(*args)

@log("ERROR")
def just_print():
    """just print Hello World string"""
    print("Hello World")

n = my_sum(range(0, 10))
print(n)
just_print()

输出:

Log[INFO]: call my_sum()
Log[INFO]: end call my_sum()
45
Log[ERROR]: call just_print()
Hello World
Log[ERROR]: end call just_print()

@wraps()的作用

functools.wraps 则可以将原函数对象的指定属性复制给包装函数对象, 默认有 _module_、_name_, _doc_
如果打印just_print._name_和 just_print._doc_

print(just_print.__name__)
print(just_print.__doc__)

输出:

just_print
just print Hello World string

如果我们把log装饰器函数里的@wraps()注释删掉,那么则输出:

inner_wrapper
None
上一篇下一篇

猜你喜欢

热点阅读