内部装饰器函数如何查看装饰函数参数? [复制]

Posted

技术标签:

【中文标题】内部装饰器函数如何查看装饰函数参数? [复制]【英文标题】:How do inner decorator functions see decorated-function arguments? [duplicate] 【发布时间】:2019-07-29 22:00:25 【问题描述】:

我正在尝试征服自开始使用以来我一直避免使用的最后一个基本 Python 功能:装饰器。我没有像使用 list-comps 那样对它进行摸索,而且我不明白装饰器声明中的内部函数是如何工作的。

这是我的意思的一个例子。鉴于此块代码:

def outer(func):
    def inner(*args, **kwargs):
        print('Hi my name is ')
        return func(*args, **kwargs)
    return inner

@outer
def decorated(name):
    print(name)


decorated('Bob')

我知道这会打印出来

Hi my name is
Bob

但我不明白的是inner如何从decorated()获得任何*args**kwargs

我的理解是这样的

@outer
def decorated(name):
    print(name)
decorated("Bob")

相当于outer(decorated("Bob"))。如果是这种情况,inner() 将如何访问name 参数?除了语法问题,我希望 inner 的声明看起来像 def inner(func.args, func.kwargs):

这里发生了什么?我误会了什么?

【问题讨论】:

Inner itself 被定义为一个接受*args**kwargs 的函数,这不是装饰器提供的东西。 所以@语法的一部分是否涉及将函数参数传递给inner @outer 被调用来替换decorated,所以decorated("Bob")inner('bob') 【参考方案1】:

我的理解是这样的

@outter
def decorated(name):
    print(name)
decorated("Bob")

相当于outter(decorated("Bob"))

错了。相当于outter(decorated)("Bob")decorated 被替换为outer(decorated) 的返回值(即inner)。当您拨打decorated 时,您实际上是在拨打inner

您可以以交互方式检查:

>>> def outter(func):
...     def inner(*args, **kwargs):
...         print('Hi my name is ')
...         return func(*args, **kwargs)
...     return inner
...
>>> @outter
... def decorated(name):
...     print(name)
...
>>> decorated
<function outter.<locals>.inner at 0x7f5aec3461e0>

【讨论】:

感谢您提供交互式检查提示。我多次解释了装饰器(和 HOF),但从未使用过交互式 Python。 @AlexYu:最佳实践是使用 @functool.wraps 将名称、文档字符串和其他元数据和属性等内容复制到替换包装函数中,在这种情况下,decorated 引用几乎完全相同的repr() 输出,这就是为什么您不能在现实生活中简单地回显修饰的函数对象。一个糟糕的替代方法是回显decorated.__code__,它只包含名称inner,而不是完整的__qualname__ @MartijnPieters 我知道最佳实践。但是当我向某人解释某件事时:首先是对内部工作的解释,然后才是“最佳实践”和“为什么它们是最好的”和“它们真的是最好的” @AlexYu:很好,但我的意思是很多人会在框架或标准库中遇到装饰器,此时 Jonas 的说明就会失败。这是您看不到太多交互式演示的原因之一。 @MartijnPieters 好的。在编写实际代码时,您是绝对正确的。但在一个人能够编写代码之前 - 他们必须被教导如何去做。这就是交互式探索很棒的地方

以上是关于内部装饰器函数如何查看装饰函数参数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

闭包和装饰器

python装饰器获取内部函数的变量值

python装饰器获取内部函数的变量值

python_如何定义带参数的装饰器?

装饰器

闭包和装饰器