Python basics: 5: decorator and python Basics

Source: Internet
Author: User

Python basics: 5: decorator and python Basics

The modifier adds additional functions to existing objects.

Based on the open and closed principle, some functions are added before or after the call without changing the caller;

When you have 100 or more calling programs that need to add/modify the same content at the same time, it is very useful to use the decorator;


Case 1: assume that all the 100 programs require an additional function, such as printing the character log before executing the program;

One implementation method is to copy this function to 100 programs, but the disadvantage is that the outer and f execution sequence cannot be flexibly controlled, and it is very troublesome to modify, you need to modify a program.

In this case, a decorator is needed to encapsulate a function.

# Define the decorator
Def outer (): # defines the function outer outside the general program to print logs.
Print ('log ')
# Use decorator
Def f1 ():
Outer () # Use decorator
Print ('f1 ')
Def f2 ():
Outer ()
Print ('F2 ')
Def f100 ():
Outer ()
Print ('f100 ')
# Execution Program
Print ('f1 execution result :')
F1 ()
Print ('f2 execution result :')
F2 ()
Print ('f100 execution result :')
F100 ()

Execution result:

To understand the decorator, you must first understand the function. For details, refer to another blog.

Two basic functions:

1) when the function is executed from top to bottom, the last variable/function will overwrite the previous variable/parameter.

def f1():
print(123)

def f1():
print(456)
f1()

# Because the execution order is from top to bottom, the last f1 will overwrite the previous f1 and the execution result is 456.


Example of function execution sequence:

2) functions can be passed as a whole. If the passed function name is not added with (), the function is passed as a whole.

# First pass f1 to the xxx of f2 as a whole, and then execute the function body in f2. Because the function body of f2 is xxx (), continue to execute f1 ()
Def f1 ():
Print ("function 1 execution", 123)

Def f2 (xxx ):
Print ("function 2 execution", 456)
Xxx () # execute f1 ()
F2 (f1) # Pass f1 to xxx, then xxx = f1

Execution result:


The modifier @ + function name has two major functions:

1) automatically execute the outer function, and pass the decorated function name f1 below as a parameter to the parameter in the decorator;

2) Assign the return value of the outer function to f1 again.


Case 2: explains how the decorator works: no other functions are available in the decorator.

Case 2-1: no decorator case: Execute f1 ()

1) store the return value

Def f1 ():
Print ('f1 ')
Return 123 # f1 returns 123
F1 () # execute the f1 function body and the execution result is F1

Execution result:

2) do not store the return value

Def f1 ():
Print ('f1 ')
Return 123 # f1 returns 123
R = f1 () # execute the f1 function body and assign the return value of f1 to r
Print (r) # print 123 directly because the f1 function has a return value.

Execution result:


Case 2-2: After adding the decorator: Execute f1 (), the original f1 function body will be modified, and the original function body will no longer be executed.

Case study:

  • The function is executed from top to bottom. When def f1 () is executed, the decorator above it will pass f1 under the decorator as a parameter to the decorator, replace the parameter func In the decorator;

  • The function body of f1 will not be executed. For example, print ('f1 ') will not appear.

  • After the decorator executes the value 111, it is re-assigned to f1, so the current value of f1 is 111.

  • If you execute f1 (), that is, execute 111 (), an error will occur.

1) because the value returned by the decorator is 111, and f1 executes 111 (), this will cause an error.
Def outer (func ):
Returned "111"
@ Outer # decorator
Def f1 ():
Print ('f1 ')
Return "123" # f1 returns 123
F1 () # Because f1 has been assigned a value of 111 again, if f1 () is executed, 111 () is executed. If f1 is executed again, an error occurs.

Execution result: execution result with an error

2) Check the value of f1 at this time. The execution result is 111.
Def outer (func ):
Returned "111"
@ Outer # decorator
Def f1 ():
Print ('f1 ')
Return "123" # f1 returns 123
Print (f1) # Because f1 has been assigned a value of 111 again


Case 3: decorator Working principle: built-in function in decorator, no func Parameter

Case 3-1: parameters that the function under the decorator will pass to the decorator

Case study: Execute the decorator, assign f1 to func, and define the inner function. The return value of the decorator is the inner function, and assign the value to f1. Then, when f1 () is executed, execute inner () and the result is "Print inner function"

# Functions in the decorator
Def outer (func): # func is the old f1
Def inner (): # define inner. The inner function body below
Print ("execute inner function body ")
Return inner # inner refers to the inner function body and assigns this function body to f1.

@ Outer
Def f1 ():
Print ('execute the f1 function body ')
Return "123" # f1 returns 123
F1 () # f1 has been re-assigned as inner. Therefore, when f1 () is executed, inner () is executed ()

Execution result:


Case 4:Decorator Working principle:Built-in functions in the decorator with the func parameter.

Because f1 will be replaced with the return value of the decorator, the decorated parameter func refers to the old f1, The New f1 is inner, and the inner function has no return value.

1) print the character log before executing the program

Def outer (func): # func is the original f1
Def inner (): # define the inner function
Print ('inner function: log ')
Func () # Because func represents the original f1, the original f1 function is executed.
Return inner # This is the return value of the decorator and is assigned an f1 value.

@ Outer
Def f1 ():
Print ('execute the f1 function body ')
Return "123" # f1 returns 123
F1 () # execute the inner function in the decorator.

Execution result:

2) print the character log first, then execute the program, and then print after:

Def outer (func): # func is the original f1
Def inner (): # define the inner function
Print ('inner function: log ')
Func () # Because func represents the original f1, the original f1 function is executed.
Print ('after ')
Return inner # This is the return value of the decorator and is assigned an f1 value.

@ Outer
Def f1 ():
Print ('execute the f1 function body ')
Return "123" # f1 returns 123
F1 () # execute the inner function in the decorator.

Execution result:

Case 5: the inner layer function of the decorator has a return value.

Print the character log first, then execute the program, take the return value of the old program, and then print after:

Def outer (func): # func is the original f1
Def inner (): # define the inner function
Print ('inner function: log ')
R = func () # Because func represents the original f1, execute the original f1 function body and pass the return value of the old f1 to r, that is, r = "f1 return value 123"
Print ('after ')
Return r # The final return value of the inner function is a person. If the function encounters return, it will not be executed below.
Return inner # This is the return value of the decorator and is assigned an f1 value.

@ Outer
Def f1 ():
Print ('function body executing f1 ')
Return "f1 return value 123" # f1 returns 123
R = f1 () # execute the inner function in the modifier and take the return value of the inner function, that is, r
Print (r)

Execution result:


Here we can summarize the execution sequence of the accessories:


Case 6 and case 7 explain the internal function parameters:

Case 6: parameters in the decorator: When f1 has parameters, you also need to enter parameters in the decorator.

Def outer (func): # func is the original f1
Def inner (a): # define the inner function
Print ('inner function: log ')
R = func (a) # Because func represents the original f1, execute the original f1 function body and pass the return value of the old f1 to r, that is, r = "f1 returns 123"
Print ('after ')
Return r # The final return value of the inner function is a person. If the function encounters return, it will not be executed below.
Return inner # This is the return value of the decorator and is assigned an f1 value.

@ Outer
Def f1 (arg ):
Print (arg)
Return "f1 return value 123" # f1 returns 123
R = f1 ("f1 requires Parameters") # parameters need to be passed
Print (r)

Execution result:


Case 7: when the number of parameters in the decorator: f1. .. f100 is inconsistent, dynamic parameters must be used.

Def outer (func): # func is the original f1
Def inner (* args, ** kwargs): # defines the inner function and uses dynamic parameters.
Print ('inner function: log ')
R = func (* args, ** kwargs) # Because func represents the original f1, execute the original f1 function and pass the return value of the old f1 to r, that is, r = "f1 returns 123"
Print ('after ')
Return r # The final return value of the inner function is a person. If the function encounters return, it will not be executed below.
Return inner # This is the return value of the decorator and is assigned an f1 value.

@ Outer
Def f1 (arg ):
Print (arg)
Return "f1 return value 123" # f1 returns 123
@ Outer
Def f2 (arg1, arg2 ):
Print (arg1, arg2)
Return "f2 return value 456" # f1 returns 123

R1 = f1 ('f1 passes 1 parameter ')
Print (r1)
Print ('-------- example of passing two parameters --------')
R2 = f2 ("f2 transfer parameter 1", "f2 transfer parameter 2 ")
Print (r2)
Execution result:


Case link: https://pan.baidu.com/s/1dFvrRS9 password: 27cj






Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.