1

正如 's 文档中的memoization 示例中所述decorator,您不能使用嵌套函数方法来实现 memoization,同时保留函数签名。相反,您必须将内部函数取出,然后创建一个简单的装饰器函数:

def _memoize(func, *args, **kwargs):
    # the memoization code

def memoize(f):
    f.cache = {}
    return decorator(_memoize, f)

为什么我不能使用内部函数?或者文档是否具有误导性,这意味着有一种方法可以将内部函数与@decorator? 为什么会这样,是否有某种实际的、基于实施的原因,还是我真的被迫以别人的方式去做?我讨厌辅助函数,并希望尽可能避免这种方法;如果有一个 hack 让它工作(当然,没有自己从头开始编写),我想听听它是什么。

应该注意的是,不需要初始化cache或任何其他不属于内部函数的代码,当然,@decorator完全不使用外部函数就可以正常工作(但话又说回来,为什么要使用内部函数当您在内部函数之外没有代码时?)。

4

1 回答 1

3

要求这是decorator库的有意设计选择,在文档中进行了解释(强调原文):

与基于嵌套函数的 memoize_uw 方法的不同之处在于,装饰器模块强制您在外层提升内部函数(平面优于嵌套)。

这在引言的动机部分也有解释:

例如,装饰器的典型实现涉及嵌套函数,我们都知道平面比嵌套更好。

当然,“平面优于嵌套”是Python 之禅的一部分。但是你可能不同意它在这里适用,或者可能认为其他一些原则会凌驾于它之上。

如果你强烈反对图书馆背后的设计原则,你可能不会对它感到满意。


如果您查看源代码,您会发现该模块利用了您将要传递顶级函数的假设。例如,它复制func_globals,但不尝试复制非局部闭包单元,它希望inspect有一个模块级函数可以使用。在许多情况下,违反这些假设实际上并不会伤害您。但是如果你坚持这样做,你就必须对代码有足够的了解,才能知道它什么时候伤害你。

于 2013-08-01T22:21:47.747 回答