如 memoization example 中所述在decorator
的文档中,您不能使用嵌套函数方法来实现记忆化,同时保留函数签名。相反,您必须将内部函数取出,然后创建一个简单的装饰器函数:
def _memoize(func, *args, **kwargs):
# the memoization code
def memoize(f):
f.cache = {}
return decorator(_memoize, f)
为什么我不能使用内部函数?或者文档是否具有误导性,这意味着有一种方法可以将内部函数与 @decorator 一起使用? 是否有某种实际的、基于实现的原因来解释为什么会这样,或者我真的被迫按照别人的方式来做?我讨厌辅助函数,并且希望尽可能避免这种方法;如果有一个 hack 可以让它工作(当然,不需要我自己从头开始编写它),我想听听它是什么。
应该注意的是,不需要初始化缓存
或任何其他不属于内部函数的代码,当然,@decorator
可以工作根本不使用外部函数就可以了(但话又说回来,当内部函数之外没有代码时为什么要使用内部函数呢?)。
最佳答案
要求这是装饰器库的有意设计选择,文档中对此进行了解释(强调原文):
The difference with respect to the memoize_uw approach, which is based on nested functions, is that the decorator module forces you to lift the inner function at the outer level (flat is better than nested).
这也在简介的动机部分进行了解释:
For instance, typical implementations of decorators involve nested functions, and we all know that flat is better than nested.
当然,“扁平比嵌套更好”是 the Zen of Python 的一部分。但您可能不同意它在这里适用,或者可能认为其他原则凌驾于它之上。
如果您强烈反对该库背后的设计原则,您可能不会对此感到满意。
<小时/>如果你查看the source code ,您可以看到该模块利用了您将传递顶级函数的假设。例如,它复制func_globals
,但不会尝试复制非局部闭包单元,并且它期望inspect
有一个可以使用的模块级函数。在许多情况下,违反这些假设实际上不会伤害您。但如果您坚持这样做,则必须充分理解代码才能知道它何时会伤害您。
关于python - 为什么装饰器模块强制我将内部函数提升到外部水平?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18005581/