【问题标题】:How exactly works Python decorator?Python 装饰器到底是如何工作的?
【发布时间】:2020-04-08 05:39:06
【问题描述】:

我是 Python 的新手(我来自 Java 和 C#)

我正在研究 decorator 主题。所以我有以下例子:

# DECORATOR:
def my_decorator(func):
  def wrap_func():
    print('**************')
    func()
    print('**************')
  return wrap_func


@my_decorator
def hello():
  print('Hello World')

hello()

在我看来,这是逻辑(但我不确定:

我正在定义一个 my_decorator 函数,以另一个函数作为参数。这个 my_decorator 函数将作为参数传递的函数包装到执行作为参数传递的函数的 wrap_func() 函数中。另外这个 wrap_func() 函数可以在作为参数传递的函数执行前后执行一些额外的逻辑(它是对原始函数的装饰。

要告诉解释器一个特定的函数必须使用装饰器,我必须在函数定义之前使用语法 @decorator_name

所以在我的情况下:当我执行 hello() 调用时:Python 知道 hello() 函数必须由 my_decorator 装饰> 装饰器,所以它不直接执行 hello() 函数,而是执行 my_decorator() 函数,将 hello() 引用作为参数传递.因此它可以在 hello() 调用之前和之后添加额外的逻辑。

这个推理是正确的还是我错过了什么?

我还有一个疑问:为什么装饰器函数返回包装我们装饰逻辑的函数?

【问题讨论】:

标签: python python-3.x python-decorators


【解决方案1】:

装饰器只是函数调用的语法糖。

装饰

@my_decorator
def hello():
    print('Hello world')

等价于

def hello():
    print('Hello world')

hello = my_decorator(hello)

所以在这种情况下,使用装饰器语法与直接定义如下函数是一样的:

def hello():
    print('**************')
    print('Hello world')
    print('**************')

装饰器创建一个调用print('**************')的函数,然后调用original函数,然后再次调用print('**************')

如果你只打算装饰一次功能,这显然只是很多不必要的样板。但是,如果您要装饰 多个 函数,那么抽象就会得到回报:

# DECORATOR:
def my_decorator(func):
  def wrap_func():
    print('**************')
    func()
    print('**************')
  return wrap_func


@my_decorator
def hello():
  print('Hello World')

@my_decorator
def how_are_you():
  print("How are you doing?")

@my_decorator
def goodbye():
  print('Goodbye, world')

def hello():
    print('**************')
    print('Hello world')
    print('**************')

def how_are_your():
    print('**************')
    print('How are you doing')
    print('**************')

def good_bye():
    print('**************')
    print('Goodbye world')
    print('**************')

尤其是如果您后来决定使用 ============== 而不是 ************** 包装每个输出。

【讨论】:

    【解决方案2】:

    装饰器只是语法糖。这个:

    @decorator
    def func():
        pass
    

    等价于:

    def func():
        pass
    
    func = decorator(func)
    

    【讨论】:

      猜你喜欢
      • 2011-07-25
      • 2016-01-24
      • 2020-10-15
      • 2016-01-06
      • 1970-01-01
      • 2014-04-14
      • 2018-06-11
      • 2017-09-12
      • 1970-01-01
      相关资源
      最近更新 更多