测试 python 备忘录装饰器

Posted

技术标签:

【中文标题】测试 python 备忘录装饰器【英文标题】:Testing python memo decorator 【发布时间】:2014-04-28 22:19:30 【问题描述】:

我确实有以下装饰器:

def memo(f):
        """Decorator that caches the return value for each call to f(args).
        Then when called again with same args, we can just look it up."""
        cache = 

        def _f(*args):
            try:
                return cache[args]
            except KeyError:
                cache[args] = result = f(*args)
                return result
            except TypeError:
                # some element of args can't be a dict key
                return f(args)

        return _f

我需要编写一些测试来了解它是否有效。我怎样才能测试这样的装饰器? 我只设法编写了性能测试,以了解它是否可以加快功能。

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

        @memo
        def cached_fib(n):
            if n == 0:
                return 0
            elif n == 1:
                return 1
            else:
                return cached_fib(n - 1) + cached_fib(n - 2)

        t0 = time.clock()
        fib(20)
        t = time.clock() - t0

        t1 = time.clock()
        cached_fib(20)
        t2 = time.clock() - t1
        self.assertGreater(t, t2)

也许测试它是否在缓存中存储一​​些值是明智的,但我不知道如何在 python 中实现它。有什么想法吗?

【问题讨论】:

【参考方案1】:

应该为同一个参数调用一次 decoarted 函数。检查一下。

def test_memo__function_should_be_called_once_for_same_arg(self):
    @memo
    def f(arg):
        f.call_count += 1
        return arg
    f.call_count = 0

    self.assertEqual(f(1), 1)
    self.assertEqual(f(1), 1)
    self.assertEqual(f.call_count, 1)

    self.assertEqual(f(2), 2)
    self.assertEqual(f(2), 2)
    self.assertEqual(f(2), 2)
    self.assertEqual(f.call_count, 2)

顺便说一句,在cached_fib 函数中,它应该调用cache_fib,而不是fib 以利用记忆。

【讨论】:

以上是关于测试 python 备忘录装饰器的主要内容,如果未能解决你的问题,请参考以下文章

Python 装饰器自理解备忘

Python 装饰器:在测试前运行装饰器

如何在 python 中对装饰器工厂输入进行单元测试

测试 Python 装饰器?

测试包装 api 路由的装饰器

根据条件应用不同的装饰器