python - 为什么装饰器模块强制我将内部函数提升到外部水平?

标签 python python-2.7 decorator memoization python-decorators

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/

相关文章:

python - 改进图片以检测区域内的字符

python - scikit-learn, keras, tensorflow 和 mxnet 中保存机器学习模型的所有格式是什么?

Python——读取和比较行和列

python - 不重复python的排列

Python:带有包装器的装饰器的行为

python - 如何在 Python 函数中运行异步代码?

python - 无法在 Windows XP 上运行 Python EXE

javascript - 装饰在 Vue 中调用的函数弄乱了 'this' 绑定(bind)?

java - 拦截器和装饰器的区别

python - 运行本地 pip 安装时如何自定义复制到 tmp 目录中的文件?