Decorative Device (decorator) is an advanced Python syntax. Adorners can be used to process a function, method, or class . In Python, we have several methods for working with functions and classes, such as in Python closures, where we see the function object as the result of a function's return. With respect to other methods, the adorner has a simple syntax and a code with high readability. As a result, adorners are widely used in Python projects.
The adorner first appeared in Python 2.5, which was originally used to process functions and methods such as callable objects (callable object, which defines the __call__ method). In Python 2.6 and later versions of Python, adorners are further used for processing classes.
decorative functions and methods
Let's first define two simple mathematical functions, one to calculate the sum of squares and one to calculate the squared difference:
# get square sum def Square_sum (A, B): return a**2 + b**2# get square diffdef Square_diff (A, B): return a**2-b**2
Print (Square_sum (3, 4)) Print (Square_diff (3, 4))
After having basic mathematical functions, we may want to add other functions to the function, such as printing input. We can rewrite the function to achieve this:
#Modify:print Input#get square sumdefSquare_sum (A, b):Print("Intput:", A, b)returnA**2 + b**2#Get square diffdefSquare_diff (A, b):Print("input", A, b)returnA**2-b**2
Print (Square_sum (3, 4)) Print (Square_diff (3, 4))
We have modified the definition of the function to add functionality to the function.
Now, we use adorners to implement the above modifications:
defDecorator (F):defNew_f (A, b):Print("input", A, b)returnF (A, b)returnNew_f#get square sum@decoratordefSquare_sum (A, b):returnA**2 + b**2#Get square diff@decoratordefSquare_diff (A, b):returnA**2-b**2Print(Square_sum (3, 4))Print(Square_diff (3, 4))
Adorners can be defined in the form of Def, such as decorator in the code above. The adorner receives a callable object as an input parameter and returns a new callable object. The adorner creates a new callable object, which is the new_f above. In New_f, we added the function of printing and realized the function of the original function by calling F (A, B).
Once we've defined the adorner, we can use the @ syntax. Call @decorator before the function square_sum and Square_diff are defined, we actually pass square_sum or Square_diff to decorator, and assigns the new callable object returned by decorator to the original function name (Square_sum or Square_diff). So, when we call Square_sum (3, 4), it's equivalent to:
Square_sum = Decorator (square_sum) square_sum (3, 4)
We know that the variable names and objects in Python are separate. A variable name can point to any object. In essence, the adorner plays the role of re-pointing to the variable name (name binding), so that the same variable name points to a newly returned callable object, thus achieving the purpose of modifying the callable object.
Similar to the machining function, we can use the adorner to process the class method.
If we have other similar functions, we can continue to call decorator to modify the function without repeating the function or adding a new package. In this way, we improve the reusable nature of the program and increase the readability of the program.
Decorator with reference
In the above adorner call, such as @decorator, the adorner defaults to the function that follows it is the only parameter. The adorner syntax allows us to invoke decorator, providing other parameters, such as @decorator (a). This provides greater flexibility for the authoring and use of adorners.
#a new wrapper layerdefPre_str (pre="'): #Old Decorator defDecorator (F):defNew_f (A, b):Print(Pre +"input", A, b)returnF (A, b)returnNew_freturnDecorator#get square sum@pre_str ('^_^')defSquare_sum (A, b):returnA**2 + b**2#Get square diff@pre_str ('t_t')defSquare_diff (A, b):returnA**2-b**2Print(Square_sum (3, 4))Print(Square_diff (3, 4))
The pre_str above is an adorner that allows parameters. It is actually a function encapsulation of the original adorner and returns an adorner. We can interpret it as a closure with environmental parameters. When we invoke @pre_str (' ^_^ '), Python can discover this layer of encapsulation and pass parameters to the adorner's environment. The call is equivalent to:
Square_sum = Pre_str ('^_^') (square_sum)
Decoration class
In the example above, the adorner receives a function and returns a function that plays the effect of the processing function. After Python 2.6, adorners are extended to classes. An adorner can receive a class and return a class, thus playing the effect of the processing class.
defDecorator (aclass):classNewclass:def __init__(self, Age): Self.total_display=0 self.wrapped=AClass (age)defdisplay (self): Self.total_display+ = 1Print("Total Display", Self.total_display) self.wrapped.display ()returnNewclass@decoratorclassBird:def __init__(self, Age): Self.age= Agedefdisplay (self):Print("My Age is", self.age) Eaglelord= Bird (5) forIinchRange (3): Eaglelord.display ()
Python depth 05 Adorner