Day4 decorations and day4 decorations

Source: Internet
Author: User

Day4 decorations and day4 decorations

Python decorator

1. Required

Def foo ():

Print (foo)

<Function foo at 0x7f62db093f28>
>>> Foo
<Function foo at 0x7f62db093f28>

Foo is a function, function body;

Foo () is the execution of the foo function.

Def foo ():

Print (foo)

Foo = lambda x: x + 1

Foo () will execute the lambda expression instead of the original foo function, because the function foo is redefined.

2. The demand is coming

A startup company has N business departments and 1 Basic Platform department. The basic platform is responsible for providing underlying functions, such as database operations, redis calls, and monitoring APIs. When using basic functions, the business department only needs to call the functions provided by the basic platform. As follows:

############# Functions provided by the basic platform are as follows ###############
Def f1 ():

Print (f1)

Def f2 ():

Print (f2)

Def f3 ():

Print (f3)

Def f4 ():

Print (f4)

  ############## Functions provided by business department A to call the basic platform ###############

F1 ()

F2 ()

F3 ()

F4 ()

  ############## Functions provided by the basic platform are called by business department B ###############

F1 ()

F2 ()

F3 ()

F4 ()

At present, the company is proceeding in an orderly manner. However, in the past, developers on the basic platform did not pay attention to verification issues when writing code, that is, the functions provided by the basic platform can be used by anyone. Now, you need to reconstruct the functions of the basic platform and add verification mechanisms for all the functions provided by the platform. That is, verify the functions before they are executed.

The boss handed over his work to Low B. He did this:

Negotiate with each business department, write code for each business department, and verify the code before calling the basic platform function. In this way, the basic platform does not need to be modified.

Unfortunately, on that day, Low B was fired ....

The boss handed over his work to Low BB. He did this:

Only refactor the code of the basic platform, so that N business departments do not need to make any changes

  ############# Functions provided by the basic platform are as follows ###############

Def f1 ():

# Verification 1

# Verification 2

# Verification 3

Print (f1)

Def f2 ():

# Verification 1

# Verification 2

# Verification 3

Print (f2)

Def f3 ():

# Verification 1

# Verification 2

# Verification 3

Print (f3)

Def f4 ():

# Verification 1

# Verification 2

# Verification 3

Print (f4)

  ############## Functions provided by business department A to call the basic platform ###############

F1 ()

F2 ()

F3 ()

F4 ()

  ############## Functions provided by the basic platform are called by business department B ############### 

F1 ()

F2 ()

F3 ()

F4 ()

  ############## The call method of the business department remains unchanged, without affecting the business department ###############  

After a week, Low BB was fired ......

The above code is too reusable and the original code has been modified.

The boss handed over his work to Low BBB. He did this:

Only the code of the basic platform is restructured, and no modifications are required for other business departments.

Def check_login ():

# Verification 1

# Verification 2

# Verification 3

Pass

Def f1 ():

Check_login ()

Print (f1)

Def f2 ():

Check_login ()

Print (f2)

Def f3 ():

Check_login ()

Print (f3)

Def f4 ():

Check_login ()

Print (f4)

The boss looked at the implementation of Low BBB and smiled with a sigh of relief. He chatted with Low BBB for a day:

The boss said:

Code Writing should follow the principle of open and closed. Although this principle is used in object-oriented development, it is also used for functional programming. It stipulates that the implemented functional Code cannot be modified, but it can be extended, namely:

(1) closed: Implemented functional code block

(2) Openness: for extended development, new functions can be developed, but the original code should not be modified as far as possible.

If the open and closed principle is applied to the above requirements, the Code cannot be modified within the f1, f2, f3, and f4 functions. The boss is given an implementation scheme of Low BBB:

Def w1 (func ):

Def inner ():

# Verification 1

# Verification 2

Verification 3

Return func ()

Return inner

@ W1

Def f1 ():

Print (f1)

@ W1

Def f2 ():

Print (f2)

@ W1

Def f3 ():

Print (f3)

@ W1

Def f4 ():

Print (f4)

  ############## The call method of the business department remains unchanged, without affecting the business department ###############

The code above is only modified on the basic platform, so that the [verification] operation can be performed before other people call functions f1, f2, f3, and f4, other departments do not need to make any changes.

Low BBB was so scared that he asked, What is the internal execution principle of this code?

The boss was about to get angry. Suddenly the mobile phone of Low BBB fell to the ground, and the screen saver was just a picture of the girlfriend of Low BBB. The old freshman looked tight and shook his eyes with a smile, I made a friend with Low BBB. The detailed explanation begins:

Take f1 as an example:

Def w1 (func ):

Def inner ():

# Verification 1

# Verification 2

# Verification 3

Return func ()

Return inner

@ W1

Def f1 ():

Print (f1)

After writing this Code (the function is not executed, not executed, or executed), the Python interpreter will explain the code from top to bottom. The steps are as follows:

(1) def w1 (func): => load w1 to the memory and scan it To the memory.

(2) @ w1

Yes, on the surface, the interpreter will only explain the two sentences of code, because the internal code of a function will not be executed before it is called.

On the surface, the interpreter will actually execute these two sentences, but there are many articles about the @ w1 code,@ Function nameIt is a syntactic sugar (decorator) of Python ).

In the preceding example, @ w1 performs the following operations:

(1) execute the w1 function and use the function under @ wq as the parameter of the w1 function. That is, @ w1 is equivalent to w1 (f1)

Therefore, internal execution will be performed:

Def inner ():

# Verification

Return f1 () # func is a parameter. func is equivalent to f1.

Return inner # return inner, which represents a function rather than an execution function.

Actually, the original f1 function is inserted into another function.

(2) return values of the w1 function to be executed.AssignmentName of the function under @ w1

The Return Value of the w1 function is:

Def inner ():

# Verification

Return f1 () # here represents the original f1 Function

Then, the return value is re-assigned to f1, that is:

New f1 = def inner:

# Verification

Return f1 ()

Therefore, when the business department wants to execute the f1 function in the future, it will execute the New f1 function. In the new f1 function, it will first perform verification before executing the original f1 function, then, the return value of the original f1 function is returned to the business caller.

Low BBB, do you understand? If you do not understand it, I will go to your house to help you solve it !!!

3. Question and Answer time

Q: What are the parameters of the decorated function?

One parameter:

Def w1 (func ):

Def inner (arg ):

# Verification 1

# Verification 2

# Verification 3

Return func (arg)

Return inner

@ W1

Def f1 (arg ):

Print (f1)

Two parameters:

Def w1 (func ):

Def inner (arg1, arg2)

# Verification 1

# Verification 2

# Verification 3

Return func (arg1, arg2)

Return inner

@ W1

Def f1 (arg1, arg2 ):

Print (f1)

Three parameters:

Def w1 (func ):

Def inner (arg1, arg2, arg3 ):

# Verification 1

# Verification 2

# Verification 3

Return func (arg1, arg2, arg3)

Return inner

@ W1

Def f1 (arg1, arg2, arg3 ):

Print (f1)

Q: Can I decorate a decorator with functions that process n parameters?

Def w1 (func ):

Def inner (* args, ** kwargs ):

# Verification 1

# Verification 2

# Verification 3

Return func (* args, ** kwargs)

Return inner

@ W1

Def f1 (arg1, arg2, arg3 ):

Print (f1)

Q: Can a function be decorated with multiple decorators?

Def w1 (func ):

Def inner (* args, ** kwargs ):

# Verification 1

# Verification 2

# Verification 3

Return func (* args, ** kwargs)

Return inner

Def w2 (func ):

Def inner (* args, ** kwargs ):

# Verification 1

# Verification 2

# Verification 3

Return func (* args, ** kwargs)

Return inner

@ W1

@ W2

Def f1 (arg1, arg2, arg3 ):

Print (f1)

In the following example, we need to complete this process. We need to set up a webpage background. When a user logs on to a non-homepage, it needs to be verified. How can this problem be achieved?

First, we define the modules:

Def login (func ):
# Logon verification module
Print ("passed user verification ......")
Return func

Def home (name ):

# Homepage, No Logon verification required
Print ("Welcome [% s] to home page." % name)
Def TV (name ):

# TV page. You need to verify the login
Print ("Welcome [% s] to TV page." % name)
Def movie (name ):

# Movie page, login verification required
Print ("Welcome [% s] to movie page." % name)

In the above Code, we implemented several function bodies. Then, we know that to allow users to perform verification, we must first execute the login function when entering the webpage. How can we execute the function, you must call the function. after calling the function, there is a return value. We know that you only need to enter TV (name) to modify the original code and facilitate user operations, in this way, the TV module is called directly, because. We know that the program is executed in serial mode. Then, we can execute the login () module in advance and return a value. Execute the TV function.

Def login (func ):
# Logon verification module
Print ("passed user verification ......")
Return func

Def home (name ):
Print ("Welcome [% s] to home page." % name)
Def TV (name ):
Print ("Welcome [% s] to TV page." % name)
Def movie (name ):
Print ("Welcome [% s] to movie page." % name)
TV = login (TV)
# Pass TV as a parameter to the login function and return the TV parameter to perform a verification.
TV ("alex ")

The running result is as follows:

Passed user verification ......
Welcome [alex] to TV page.
Although we have executed this program perfectly. However, this program is faulty because the user inputs TV ("alex") when calling it. What will happen when the program is not called:

Def login (func ):
# Logon verification module
Print ("passed user verification ......")
Return func

Def home (name ):
Print ("Welcome [% s] to home page." % name)
Def TV (name ):
Print ("Welcome [% s] to TV page." % name)
Def movie (name ):
Print ("Welcome [% s] to movie page." % name)

TV = login (TV)
# Pass TV as a parameter to the login function, and then return the TV Parameter
# TV ("alex ")

The running result is as follows:

Passed user verification ......

At this time, we did not call the home page, but also prompted the user to perform input verification, so there is not much practical significance, so we have to find a way to make the user do not print anything when there is no call.

Def login (func ):
# Logon verification module
Print ("passed user verification ......")
Return func

Def home (name ):
Print ("Welcome [% s] to home page." % name)
@ Login
Def TV (name ):
Print ("Welcome [% s] to TV page." % name)
Def movie (name ):
Print ("Welcome [% s] to movie page." % name)

# TV = login (TV)
# Pass TV as a parameter to the login function, and then return the TV Parameter
# TV ("alex ")

# Login is equivalent to TV = login (TV). When the program is not called, the execution result is returned to allow the user to call it. This is obviously unreasonable. In this way, verification is obviously unreasonable if no call is executed. do not specify a call if you want to prevent the program from being called.

Def login (func ):
# Logon verification module
Def inner (name ):
# Set to allow the user to execute the call. Otherwise, the call is not executed.
Print ("passed user verification ......")
Func (name)
Return inner

Def home (name ):
Print ("Welcome [% s] to home page." % name)
Def TV (name ):
Print ("Welcome [% s] to TV page." % name)
Def movie (name ):
Print ("Welcome [% s] to movie page." % name)

TV = login (TV)
# Pass TV as a parameter to the login function, and then return the TV Parameter
# TV ("alex ")

In the above program, a layer of functions are nested in the verification module, so that the execution program will not execute the verification module without being called. Why? We know that to execute a function, the function name () must be added with parentheses. Therefore, we will return the memory function name during this loop and then call the function, in this way, the verification module can be executed during user authentication, but the function name is returned when the user does not call the module, therefore, functions cannot be executed.

Let's take a look at the situation of using the decorator:

Def login (func ):
# Logon verification module
Def inner (name ):
# Set to allow the user to execute the call. Otherwise, the call is not executed.
Print ("passed user verification ......")
Func (name)
Return inner

Def home (name ):
Print ("Welcome [% s] to home page." % name)
@ Login
Def TV (name ):
Print ("Welcome [% s] to TV page." % name)
@ Login
Def movie (name ):
Print ("Welcome [% s] to movie page." % name)

# TV = login (TV)
# Pass TV as a parameter to the login function, and then return the TV Parameter
TV ("alex ")
Movie ("tom ")

In the code above, we used the decorator so that the program first used the decorator during running. The decorator is equivalent to TV = login (TV) assign the value returned by the nth function to TV. When you call the TV function, the code of the TV function is not executed, but the code of the memory function, the second verification module is called directly. After the verification is complete, we specify the user printing module. In this way, we can avoid executing the verification module when the user has not called it.

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.