【问题标题】:Tracking recursion depth with Python decorators使用 Python 装饰器跟踪递归深度
【发布时间】:2019-01-12 09:07:51
【问题描述】:

我正在尝试编写一个装饰器来跟踪 Python 中递归函数的递归深度。

以递归函数为例,


def fib(n):
    if n == 0:
        return 0
    if n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

通常,要跟踪递归深度,您可以这样写


    def fib(n, level=0):
        print(level)
        if n == 0:
            return 0
        if n == 1:
            return 1
        else:
            return fib(n-1, level=level+1) + fib(n-2, level=level+1)

然而,在摆弄了一段时间的装饰器和大量的谷歌搜索之后,我不确定这是否可能。

我尝试过类似的东西


def visualise(func):
    def modify(*args, **kwargs):
        kwargs["count"] += 1
        print(kwargs["count"])
        return func(*args, **kwargs)

    return modify

@visualise
def fib(n):
    ...

fib(4, count=0)

但它抱怨count 是一个意外的关键字参数,我不太明白,因为我的印象是包装器modify 替换了所有出现的fib,但我猜不是?

我们将不胜感激。

【问题讨论】:

  • 问题是你将kwargs 传递给被包装的函数

标签: python recursion decorator


【解决方案1】:

您可以为装饰器指定级别变量,然后在函数调用中使用它,如下所示:

def visualise(func):
     visualise.level = 0
     def wrapper(*args, **kwargs):
         print("In:", visualise.level)
         visualise.level += 1
         result = func(*args, **kwargs)
         visualise.level -= 1
         print("Out:", visualise.level)
         return result
     return wrapper

【讨论】:

【解决方案2】:

你能不能把函数定义如下?

def fib(n, count=0):
    # ....

【讨论】:

  • 但是现在你需要修改原来的函数,那你还不如连个装饰器都没有。
【解决方案3】:

这是previous answer from Lev Zakharov above 的基于类的方法

from functools import wraps
class Visualize(object):
    def __init__(self):
        self.level = 0

    def __call__(self, func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print("In:", self.level)
            self.level += 1
            result = func(*args, **kwargs)
            self.level -= 1
            print("Out:", self.level)
            return result
        return wrapper

@Visualize()
def fib(n):
...

关于@wrapshere

【讨论】:

    猜你喜欢
    • 2010-10-25
    • 1970-01-01
    • 2019-11-07
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-05
    • 2012-03-12
    • 2016-12-02
    相关资源
    最近更新 更多