【问题标题】:Function Decorators in PythonPython 中的函数装饰器
【发布时间】:2020-07-13 08:45:00
【问题描述】:

我是 python 的初学者,我正试图围绕 python 中的函数装饰器。而且我无法弄清楚函数是如何返回函数的。

我的意思是解释器以什么顺序解释这个函数:

def decorator(another_func):
    def wrapper():
        print('before actual function')
        return another_func()
    print('pos')
    return wrapper

这两种说法有什么区别:-

return wrapper

return wrapper()

我正在使用 Head First Python,但是我觉得这个主题在那里描述得不是很好,请推荐任何视频或好的资源,以便我理解它。

【问题讨论】:

  • "请推荐任何视频或好的资源" => 这里是 OT - 最好的资源是官方语言文档和 CPython 源代码。

标签: python function return python-decorators


【解决方案1】:

理解差异的关键是理解 everything 在 python 中是一个对象,包括函数。当您使用不带括号的函数名称 (return wrapper) 时,您将返回实际函数本身。当您使用括号时,您正在调用该函数。看看下面的示例代码:

def foo(arg):
    return 2

bar = foo
baz = foo()
qux = bar()
bar()

如果您打印 baz 或 qux,它将打印两个。如果您打印bar,它将为您提供引用该函数的内存地址,而不是数字。但是,如果您调用该函数,您现在正在打印 th

的结果

【讨论】:

    【解决方案2】:

    我不知道函数是如何返回函数的。

    正如 LTheriault 已经解释的那样,在 python 中一切都是对象。不仅如此,所有事情都发生在运行时——def 语句是一个可执行语句,它从def 块中的代码创建一个function 对象,并将该对象绑定到当前命名空间中的函数名—— IOW 它主要是一些您可以手动编码的操作的语法糖(不过,这是一种非常受欢迎的语法糖 - “手动”构建一个函数对象需要大量工作)。

    请注意,将函数作为“一等公民”并不是 Python 特有的——这是functional programming 的基础。

    我的意思是解释器以什么顺序解释这个函数:

    def decorator(another_func):
        def wrapper():
            print('before actual function')
            return another_func()
        print('pos')
        return wrapper
    

    假设decorator函数在模块顶层声明:运行时首先获取def语句后面的代码块,将其编译为code对象,创建function对象(实例'function' 类型)从这个 code 对象和其他一些东西(参数列表等),最后将此函数对象绑定到声明的名称(nb: 'binds' => "assigns to")。

    内部def语句实际上只在调用外部函数时执行,每次调用外部函数时都会重新执行-IOW,每次调用decorator都会返回一个新的函数实例。

    上面的解释当然是相当简化的(因此部分不准确),但理解基本原理就足够了。

    【讨论】:

      猜你喜欢
      • 2014-07-21
      • 1970-01-01
      • 2019-12-18
      • 1970-01-01
      • 2018-10-03
      • 2016-09-27
      • 1970-01-01
      • 2017-01-06
      • 2015-09-17
      相关资源
      最近更新 更多