为什么装饰器不能使用内置功能?

imp*_*ity 0 python decorator built-in python-decorators

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

为什么这样做:

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

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


greet()
Run Code Online (Sandbox Code Playgroud)

不是这个吗?:

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

@decorator1
print("Hello!")
Run Code Online (Sandbox Code Playgroud)

是因为打印功能是在现场执行的,并且greet()仅在定义功能之后才运行@decorator1

Mar*_*ers 6

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

但是,您试图将语法应用于一个表达式语句,该表达式语句调用print()函数。最多可以修饰返回值(对于该print()函数,返回值始终为None)。

装饰器不过是语法糖。语法

@decorator_expression
def functionname(...): ...
Run Code Online (Sandbox Code Playgroud)

被执行为

def functionname(...): ...

functionname = decorator_expression(functionname)
Run Code Online (Sandbox Code Playgroud)

但没有functionname被分配两次。

因此,要进行装饰print,请显式调用装饰器:

decorated_print = decorator1(print)
decorated_print("Hello!")
Run Code Online (Sandbox Code Playgroud)

注意:我在这里明确选择了一个不同的名称,以将装饰器函数的结果分配给该名称。您可以使用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!
<>=========================<>
Run Code Online (Sandbox Code Playgroud)