简体   繁体   English

Python 装饰器究竟是如何工作的?

[英]How exactly works Python decorator?

I am absolutly new in Python (I came from Java and C#)我绝对是 Python 新手(我来自 Java 和 C#)

I am stufying the decorator topic.我正在研究装饰器主题。 So I have the following example:所以我有以下例子:

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


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

hello()

It seems to me that this is the logic (but I am not sure of this:在我看来,这就是逻辑(但我不确定这一点:

I am defining a my_decorator function taking another function as parameter.我正在定义一个以另一个函数作为参数的my_decorator函数。 This my_decorator function wrap the function passed as parameter into a wrap_func() function that execute the function passed as parameter.这个my_decorator函数将作为参数传递的函数包装到一个wrap_func()函数中,该函数执行作为参数传递的函数。 In addition this wrap_func() function can perform some extra logic before and after the execution of the function passed as parameter (it is decorating the original function.另外这个wrap_func()函数可以在作为参数传递的函数执行前后执行一些额外的逻辑(它是装饰原始函数。

To say to the interpreter that a specific function have to use the decorator I have to use the syntax @decorator_name before the function definition.要对解释器说特定函数必须使用装饰器,我必须在函数定义之前使用语法@decorator_name

So in my case: when I perform hello() call: Python know that the hello() function have to be decorated by my_decorator decorator so it is not directly executing the hello() function but it is performing the my_decorator() function passing hello() reference as parameter.所以在我的例子中:当我执行hello()调用时:Python 知道hello()函数必须由my_decorator装饰器装饰,所以它不是直接执行hello()函数而是执行my_decorator()函数传递hello ()引用作为参数。 So it can add extra logic before and after the hello() invoaction.因此它可以在hello()调用之前和之后添加额外的逻辑。

Is this reasoning correct or am I missing something??这个推理是正确的还是我错过了什么?

I have another doubt: why the decorator function return the function that wrap our decoration logic?我还有一个疑问:为什么装饰器函数返回包装我们装饰逻辑的函数?

A decorator is just syntactic sugar for a function call.装饰器只是函数调用的语法糖。

The decoration装修

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

is equivalent to相当于

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

hello = my_decorator(hello)

So in this case, using the decorator syntax is the same as defining the following function directly:所以在这种情况下,使用装饰器语法与直接定义以下函数是一样的:

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

The decorator creates a function that calls print('**************') , then calls the original function, then calls print('**************') again.装饰器创建一个函数,调用print('**************') ,然后调用原始函数,然后调用print('**************')再次。

If you had only planned on decorating once function, this is obviously just a lot of unnecessary boiler plate.如果你只打算装饰一次函数,这显然只是很多不必要的样板。 But if you were decorating multiple functions, the abstraction pays off:但是,如果您要装饰多个函数,则抽象是值得的:

# 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')

vs对比

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('**************')

especially if you later decide to wrap each output with ============== instead of ************** .特别是如果您后来决定用==============代替**************包装每个输出。

Decorators are just a syntactic sugar.装饰器只是一种语法糖。 This:这个:

@decorator
def func():
    pass

is equivalent to this:相当于:

def func():
    pass

func = decorator(func)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM