【问题标题】:Why do decorators not work with built in functions?为什么装饰器不能与内置函数一起使用?
【发布时间】:2019-06-23 11:21:08
【问题描述】:

我正在学习如何在 Python 中使用装饰器,并且对它有深入的了解,但我有一个问题 - 为什么我不能将装饰器用于内置函数?

为什么会这样:

def decorator1(func):
    def inner(*args, **kwargs):
        print("<>=========================<>")
        func(*args, **kwargs)
        print("<>=========================<>")
    return inner

@decorator1
def greet():
    print("Hello!")


greet()

不是这个?:

def decorator1(func):
    def inner(*args, **kwargs):
        print("<>=========================<>")
        func(*args, **kwargs)
        print("<>=========================<>")
    return inner

@decorator1
print("Hello!")

是不是因为print函数是现场执行的,而greet()函数只定义了,只在@decorator1之后运行?

【问题讨论】:

  • 因为装饰器装饰的是函数,而不是函数调用
  • 装饰器可以很好地使用内置函数。还有其他问题。
  • @MartijnPieters 这对我不起作用;我在 Mac OS Mojave 上使用 Python 3.7.1...
  • 我没有说你的方法有效。 :-) 只要你知道如何应用它们,装饰器就可以处理内置函数。

标签: python decorator python-decorators built-in


【解决方案1】:

@decorator 的语法只能与def ... function definitionclass ... class definition 语句一起使用。这并不意味着您不能“装饰”内置函数。

但是,您尝试将语法应用于expression statement,即calls print() 函数。最多你会装饰返回值(对于print() 函数,返回值总是None)。

然而,装饰者只是syntactic sugar。语法

@decorator_expression
def functionname(...): ...

被执行为

def functionname(...): ...

functionname = decorator_expression(functionname)

但没有将functionname 分配给两次。

所以要装饰print,显式调用装饰器:

decorated_print = decorator1(print)
decorated_print("Hello!")

注意:我在这里明确选择了一个 不同的 名称来分配装饰器函数的结果。如果您真的愿意,也可以使用print = decorator1(print)。但是您可能想稍后运行del print 以取消屏蔽内置函数,或者使用builtins.print 再次访问原始函数。

演示:

>>> def decorator1(func):
...     def inner(*args, **kwargs):
...         print("<>=========================<>")
...         func(*args, **kwargs)
...         print("<>=========================<>")
...     return inner
...
>>> decorated_print = decorator1(print)
>>> decorated_print("Hello!")
<>=========================<>
Hello!
<>=========================<>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    相关资源
    最近更新 更多