Python-basics-decorators

Source: Internet
Author: User

first, The function-related basis 1, Python is the execution of code from the top down, when the code block defining the function is not immediately executed. The corresponding code block is only executed until the function is Called.
def foo ():    print ("foo" function is running!) If the function is defined in this way, the statement inside the Foo function will not be executed. The Python interpreter simply defines a memory address in memory called Foo. equivalent: foo = print ("foo" function is running!) Look again, the following example: def foo ():    print ("i am the function definition Above!") def foo ():    print ("i am the function definition Below!") Foo () run Result: I am the following function definition!

As you can see, Python executes the code from the top down, and the following Foo overwrites the above foo. therefore, the last execution is the second defined function foo. The placement of code in Python is a requirement and cannot be placed at will, and the function body should be placed before the called Statement.

2. Function body
def foo ():    print ("foo" function is running!)    return "ok" to run: foofoo () function name: foo function body: 1-3 rows return value: string "ok", if not defined, returns the memory address of the None function by Default: when the function body is read into memory by the Python interpreter, It has an identifier that is the function of the name Foo refers to, in short, foo points to the functions of the body in memory location function name parentheses: foo (), function call method, only see this parenthesis, the program will be based on the function name from memory to find the function body and Execute.

second, The decoration device

Let's look at the following example:

def outer (func):    def inner ():        print ("i am the inner layer Function!") ")    return innerdef foo ():    print (" I am the original function! ") ")    Outer (foo) outer (foo ())

In python, everything is an object, and the function is no Exception. You can therefore call the function name and even the function name in parentheses as the return value of the other Function.

In the above code, outer and Foo are two functions, outer (foo) means to pass the foo function name as an argument to the outer function and execute the outer function; outer (foo ()) means the return value after the Foo function executes as a parameter Pass to the outer function and execute the outer function, because the Foo function does not specify a return value, it is actually passed to the outer function a NONE. Note The difference, there is no parenthesis is the key!

similarly, inside the outer function, a inner,inner is returned as a function defined inside the outer function, noting that because inner does not have parentheses behind it, it returns the function body of inner, which is actually the name inner, a simple reference.

so, What if the outer function returns inner ()? Now you should be clear that it will execute the contents of the inner function first, then return none to Outer,outer and return this none to the object that called it.

Keep in mind that function names, function parentheses can be passed as arguments or return values, and there are no brackets that are two distinct meanings!

third, The use of the decorative device scene

Adorners are typically used to add additional functionality to the existing function code and functionality without changing it. For example, before the original function executes the point of what, after the execution of the point what.

In software development There is a principle of "open-closed" principle, in short, he stipulates that the function code that has been implemented is not allowed to be modified, but can be extended, namely:

    • Closed: implemented function code block
    • Open: for extended development
There is a large company, the underlying platform department responsible for the development of internal applications and APIs there are hundreds of business units responsible for different businesses, they each call the basic Platform Department provides different functions to handle their own business situation as Follows: # Basic Platform department developed hundreds of functions def F1 (): Print (" Business Unit 1 Data Interface ... ") def f2 (): print (" business Unit 2 Data Interface ... ") def f3 (): print (" business Unit 3 Data Interface ... ") def f100 (): print (" business Unit 100 data Interface ... ") #各部门分别调用f1 () f2 () f3 () F100 () since the company was developing these functions in the early stages of its startup, the basic platform department did not secure authentication for function calls due to various reasons such as time, such as ill-conceived, etc. now, the director of the platform decided to compensate for the flaw, so: def F1 (): #加入认证程序代码 print ("business Unit 1 Data Interface ...") def F2 (): # Join the Certification Program code print ("business Unit 2 data Interface ...") D EF F3 (): # Add the Certification Program code print ("business Unit 3 Data Interface ...") def f100 (): #加入认证程序代码 print ("business Unit 100 Data Interface ..."), and A. F2 () F3 () f100 () ######################### #def login (): print ("authentication Successful!") ") def F1 (): login () print (" business Unit 1 Data Interface ... ") def f2 (): login () print (" business Unit 2 Data Interface ... ") def f3 (): log In () print ("business Unit 3 Data Interface ...") def f100 (): login () print ("business Unit 100 Data Interface ...") #各部门分别调用f1 () F2 () f3 () f100 () ############ The ############# #以上实现方法虽然可行, But it modifies the functionality code that has been implemented INTERNALLY. Violating the "open-closed" principle and continuing to look Down: def outer (func): def inner (): print ("authentication Succeeded!") "result = Func () print ("log added Successfully") return result return inner@outerdef F1 (): print ("business Unit 1 Data interface. ....) @outerdef F2 (): print ("business Unit 2 data Interface ...") @outerdef F3 (): print ("business Unit 3 Data Interface ...") @outerdef f100 (): Print ("business Department 100 Data Interface ... ") #各部门分别调用f1 () f2 () f3 () f100 () for the code above, but also to extend the code of the underlying platform, you can implement authentication operations before other departments invoke functions F1 F2 F3 f100. The log is saved at the end of the operation, and other business units do not have to change their own code to make any Changes.

Analyze the above code:

1, The program starts to run, reads from the top, discovers the function body and loads the function body into memory, and then continues to read Down.

2, when read @outer, python know that @outer is an adorner (syntax sugar), immediately execute outer this Function.

3, because the outer function did 2 things, one is to define inner this function, and the second is to return inner in memory address.

4, due to the grammatical rules of the adorner, the name of the decorated function is passed as a parameter to the adornment Function. The adornment function executes its own code sequentially, assigning its return value to the decorated Function.

5. When executing the outer function, the Python interpreter discovers another function inner, but does not immediately execute the contents of the inner code BLOCK. The next step is return Inner. The return value is a function name. From the 4th, inner This function name will be copied to F1 the decorated function, that is F1 = Inner. At this point the F1 function is overwritten by the new function inner. (that is, F1 The memory address of the function name points to the function memory address of the Inner)

An adorner: def deco (func):    def inner ():        print ("this is the inner Function")        result = Func ()        return result    return Inner@decodef func1 ():    print ("this is Func1") func1 () is actually equivalent to: fun1 = Deco (func1)

6. The business unit still calls the F1 function through F1 (), but executes the code of the inner function, which is no longer the code of the original F1 Function.

Attention:

1, @outer and @outer () are different, without parentheses, the outer function will still be executed. This differs from the traditional use of parentheses to invoke functions, which require special Attention.

2. F1 This function name is passed as a parameter to the adornment function Outer,func = f1, @outer equals outer (f1), actually passes F1 's function body instead of the return value after f1.

3, outer function Return is inner This function name, not inner () is called after the return Value.

four, the parameter transfer of the adorner
Condition of one parameter: def outer (func):    def inner (username):        print ("authentication Successful!")        result = Func (username)        print ("log added Successfully")        return result    return inner@outerdef F1 (name):    Print ( "%s is connecting to business Unit 1 Data Interface ..."%name) # Call method F1 ("jack") in the definition part of the inner function also add a parameter, call the Func function when passing this parameter, very well understand it? But then again, the other department calls the F2 with 2 parameters? F3 have 3 parameters? How do you pass it? Very simple, we have *args and **kwargs! Known as "universal parameters"! Simply modify the above Code: def outer (func):    def inner (*args,**kwargs):        print ("authentication Successful!")        result = Func (*args,**kwargs)        print ("log added Successfully")        return result    return inner@outerdef F1 (name,age ):    print ("%s is connecting to business Unit 1 Data Interface ..."%name) # Call method F1 ("jack", 18)

V. Decorator advanced usage 1, A function is decorated with multiple adorners:
def outer1 (func):    def inner (*args,**kwargs):        print ("authentication Successful!")        result = Func (*args,**kwargs)        print ("log added Successfully")        return result    return innerdef outer2 (func):    def inner (*args,**kwargs):        print ("a Welcome message ...        result = Func (*args,**kwargs)        print ("a farewell message ... ")        return result    return inner@outer1@outer2def F1 (name,age):    print ("%s is connecting to business Unit 1 Data Interface ... "%name) # Call method F1 ("jack", 18) execution result: authentication successful! A welcome message ... Jack is connecting the Business Unit 1 Data Interface ... A farewell message ... Log added successfully

Analysis:

Multiple adorners:

F1 = Outer1 (outer2 (f1))

2, with parameters of the Adorner:
# authentication Function def auth (request,kargs): print ("authentication Successful!") ") # log function def log (request,kargs): print (" log added successfully ") # adorner Function. Receives two parameters, both of which should be the name of a Function. def Filter (auth_func,log_func): # The first layer of encapsulation, the F1 function is actually passed to main_fuc this parameter def outer (main_func): # Second layer package, auth and log function parameter values Was passed Here. def Wrapper (request,kargs): # The following Code's judgment logic is not important, it is important that the reference and return value of the parameter Before_result = Auth (request            , Kargs) if (before_result! = None): return before_result;            Main_result = Main_func (request,kargs) If (main_result! = None): return main_result;        After_result = Log (request,kargs) If (after_result! = None): return after_result; Return wrapper return outer# Note that the adorner function here has parameters oh, it means to first execute the filter function # and then return the filter Function's return value as the name of the adorner function here, so, # actually here, Filter (auth , Log) = outer, @Filter (auth,log) = @outer @filter (auth,log) def F1 (name,age): print ("%s is connecting to business Unit 1 Data Interface ..."%name) # Caller FA F1 ("jack", 18) running result: certified successful! Jack is connecting the Business Unit 1 Data Interface ... Log added successfully

Analysis:

Adorner with Parameters:

F1 = Filter (auth,log) (f1)

3.multiple adorners with parameters:
Multiple adorners with parameters: @deco1 (deco_arg) @deco2 () def foo (): pass is    actually equivalent to: def foo ():    passfoo = deco1 (deco_arg) (deco2 (foo))

Analysis:

Multiple adorners with Parameters:

Deco1 accepts parameter deco_arg, finishes processing the finished result as adorner to decorate Deco2 (foo)

Python-basics-decorators

Related Article

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.