python decorator

实现一个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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容