如decorator
文档中memoization example所述,您不能使用嵌套函数方法在保留函数签名的同时实现memoization。相反,你必须解除内部函数,然后创建一个简单的装饰函数:
def _memoize(func, *args, **kwargs):
# the memoization code
def memoize(f):
f.cache = {}
return decorator(_memoize, f)
为什么我不能使用内部函数?或者文档是误导性的,这意味着有一种方法可以使用@decorator
的内部函数? 是否存在某种实际的,基于实现的原因,为什么会这样,或者我真的被迫以别人的方式去做?我讨厌帮助函数,并且如果可能的话我想避免这种方法;如果有一个黑客让它工作(当然没有我自己从头开始写),我想听听它是什么。
应该注意的是,无需初始化cache
或任何其他不属于内部函数的代码,当然,@decorator
可以通过不使用外部来正常工作完全没有功能(但是,当内部函数之外没有代码时,为什么要使用内部函数?)。
答案 0 :(得分:3)
要求这是decorator
库的有意设计选择,在文档中解释(重点在原文中):
与memoize_uw方法(基于嵌套函数)的区别在于,装饰器模块强制您在外层提升内部函数( flat优于嵌套)。
这也在简介的动机部分中进行了解释:
例如,装饰器的典型实现涉及嵌套函数,我们都知道flat比嵌套更好。
当然,“扁平比嵌套好”是the Zen of Python的一部分。但你可能不同意它适用于此,或者可能认为其他一些原则会覆盖它。
如果你强烈反对图书馆背后的设计原则,你可能不会对它感到满意。
如果你研究the source code,你可以看到该模块使用了一个假设你将要传入顶层函数。例如,它复制func_globals
,但不会尝试复制非本地闭包单元格,并且它期望inspect
具有要使用的模块级函数。在许多情况下,违反这些假设实际上不会伤害到你。但如果你坚持这样做,你必须充分了解代码,以便知道 会伤害你的时间。