SoFunction
Updated on 2024-11-21

A Simple Understanding of Decorators in Python

Python's decorators allow you to modify the context of a function while the code is running, i.e., you can define what the function does before it executes and what it does after it executes, without changing the function itself.


First, let's define a function that outputs my personal nickname:

def my_name():
  print "Yi_Zhi_Yu"
my_name() # Yi_Zhi_Yu

What if I need to output my personal uid before I output my nickname, without changing the existing my_name function, of course, so I can use a decorator.

First, the decorator is a function, and second, it takes a parameter that indicates the function to be decorated (i.e., my_name):

def my_info(func):
  def wrapper(*args, **params):
    print 218
    return func(*args, **params)
  return wrapper

The way to then associate it with the corresponding decorated function is to write it in front of the decorated function using @my_info

@my_info
def my_name():
  print "Yi_Zhi_Yu"

Finally, when my_name is executed, it will output both my uid and my nickname.

my_name()
#218
#Yi_Zhi_Yu

In the above, the most puzzling thing is the wrapper function inside the decorator function definition, the decorator itself returns the definition of the wrapper function, and the wrapper is defined in the call to the decorated function (my_name), func represents the decorated function, to put it bluntly, the decorator is just a function that must not be altered (a) into another function (b), in b call a, before and after the call can do the so-called look like decorating work. (b), in b call a, before and after the call can do the so-called look like decoration work.
The definition of the wrapper function that is ultimately returned by my_info is not the result of the execution; only when the wrapper is actually executed is the my_name method actually executed, which is what the closure is talking about.
The arguments in the wrapper are actually the arguments passed to func (which is actually my_name).

Since a decorator is also a function, can the decorator itself be passed parameters? Yes, but you need to define a higher-order function, i.e., a function with a layer on top, e.g., I want to output my customized message, and I need to pass it a parameter.

def c_info(text):
  def my_info(func):
    def wrapper(*args, **params):
      print text
      print 218
      return func(*args, **params)
    return wrapper
  return my_info

 #Use decorators

@c_info("Tony")
 def my_name():
  print "Yi_Zhi_Yu"

 my_name()
 #Tony
 #218
 #Yi_Zhi_Yu


Compared to the previous decorator, there is only an outer layer, and the inner layer only adds a call to the outer layer's incoming parameter (text).

In short, Python supports the implementation of the oop idea of decorators in function definitions, which essentially uses the closure idea of delaying calls and adding your own implementation before and after the call.

Ps: All of the above are study notes, accompanied by their own understanding, it is inevitable that there are deviations, if you find mistakes, please correct me!