美文网首页
编写高质量Python代码的59个有效方法 第6章 内置模块 第

编写高质量Python代码的59个有效方法 第6章 内置模块 第

作者: 淡淡的咸鱼 | 来源:发表于2018-09-21 21:44 被阅读0次

调试递归函数时我们常需要打印出每一步的参数及返回值,这时写个装饰器十分高效:

def trace(func):
    def wrapper(*args, **kw):
        result = func(*args, **kw)
        print(f"{func.__name__}({args}, {kw}) --> {result}")
        return result 
    return wrapper

@trace
def fibonacci(n):
    if n in (0, ):
        return 0
    return fibonacci(n-1) + fibonacci(n-2)

fibonacci(4)
>>>
fibonacci((1,), {}) --> 0
fibonacci((0,), {}) --> 0
fibonacci((2,), {}) --> 0
fibonacci((1,), {}) --> 0
fibonacci((3,), {}) --> 0

这种写法的缺陷在于变量fibonacci变成了wrapper:

help(fibonacci)
>>>
Help on function wrapper in module __main__:
wrapper(**args, **kwargs)
print(fibonacci)
>>>
<function trace.<locals>.wrapper at 0x0000012B1C774598>

为了维护函数的接口,修饰后的函数,必须保留原函数的某些标准python属性,例如,__name__,__module__。因此我们需要wraps来装饰wrapper:

from functools import wraps

def trace(func):
    @wraps
    def wrapper(*args, **kw):
        result = func(*args, **kw)
        print(f"{func.__name__}({args}, {kw}) --> {result}")
        return result 
    return wrapper

要点

  • 内置的functools模块提供了名为wraps的装饰器,开发者定义自己的装饰器时,应用wraps对其做一些处理

相关文章

网友评论

      本文标题:编写高质量Python代码的59个有效方法 第6章 内置模块 第

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