Python decorator details

Python decorator details

Decorators are an important part of Python. Simply put: they are functions that modify the functionality of other functions. They help keep our code shorter. Most beginners don't know where to use them, so I'm going to share the areas where decorators can make your code simpler. First, let's discuss how to write your own decorators.
This may be one of the most difficult concepts to master. We will discuss only one step at a time so you can fully understand it.
Decorators let you execute code around a function
Before you learn about decorators, you should master the usage of functions, especially closures. If you are not familiar with them, you can see Python function details This article

Your first decorator

Program example:

"""
//My first decorator
version:1.0
writer:False scholar@
date:2020.02.09
"""
def Outer(func):     #Define outer functions
    def Inner():     #Defining inner functions
        print("implement func()Front")
        func()      #Execute the function passed in by the parameter
        print("implement func()after")
    return  Inner

def Hello():

    print("Hello,world")
Outer(Hello)()    # Call outer function, pass parameter
# a = Outer(Hello)
# a()

Operation result:

Before performing func()
Hello,world
 After func

We just applied the principle we learned before. This is exactly what decorators in python do! They encapsulate a function and modify its behavior in one way or another. Now you may wonder, we didn't use the @ symbol in the code? It's just a short way to generate a decorated function. Here is how we use @ to run the previous code:

Program example:

"""
//My second decorator
version:1.0
writer:False scholar@
date:2020.02.09
"""
def Outer(func):     #Define outer functions
    def Inner():     #Defining inner functions
        print("implement func()Front")
        func()      #Execute the function passed in by the parameter
        print("implement func()after")
    return  Inner
@Outer
def Hello():
    print("Hello,world")
Hello()

Operation result:

Before performing func()
Hello,world
 After func

However, there is a problem if we run the following code:

print(Hello.__name__)
Inner

This is not what we want! The Ouput output should be "Hello". The function here is replaced by Inner. It rewrites the name of our function and the docstring. Fortunately, Python provides us with a simple function to solve this problem, which is functools.wraps. Let's modify the previous example to use functools.wraps:

Program example:

"""
//My second decorator
version:1.0
writer:False scholar@
date:2020.02.09
"""
from functools import wraps
def Outer(func):     #Defining outer functions
    @wraps(func)
    def Inner():     #Defining inner functions
        print("implement func()Front")
        func()      #Execute the function passed in by the parameter
        print("implement func()after")
    return  Inner
@Outer
def Hello():
    print("Hello,world")
Hello()
print(Hello.__name__)

Operation result:

Before performing func()
Hello,world
 After func
Hello

Let's introduce the general writing method of decorator

Program example:

"""
//My third decorator
version:1.0
writer:False scholar@
date:2020.02.09
"""
from functools import wraps
def Outer(func):     #Defining outer functions
    @wraps(func)
    def Inner(*args,**kwargs):     #Defining inner functions
        if  not can_run:

            return "This function cannot be executed"
        print("This function can execute")
        return func(*args,**kwargs)      #Execute the function passed in by the parameter
    return  Inner

@Outer
def Hello():
    print("Hello,world")
can_run = False
print(Hello())
# can_run  = True
Hello()

Operation result:

This function cannot be executed
 #This function can execute
#Hello,world

Usage scenarios

To grant authorization

Decorators can help to check if someone is authorized to use an endpoint of a web application. They are widely used in the Flask and Django web frameworks. Here is an example of using decorator based authorization:

def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization    #Authentication
        if not auth or not check_auth(auth.username, auth.password):  # If there is no authentication, or the user name and password are incorrect
            authenticate()         #Execute authentication function
        return f(*args, **kwargs)
    return decorated

Journal

Log is another highlight of decorator application. This process is recorded in the log when the function is executed:

from functools import wraps
 
def logit(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print(func.__name__ + " was called")
        return func(*args, **kwargs)
    return with_logging
@logit
def addition_func(x):
   """Do some math."""
   return x + x
result = addition_func(4)

Decorator class with parameters

Program example:

"""
"""
//My fourth decorator
version:1.0
writer:False scholar@
date:2020.02.09
"""
from functools import  wraps
def Logi(files = 'log.txt'):   #Incoming log parameters
    def Outer(func): 
        @wraps(func)  
        def Inner(*args,**kwargs):
            str = func.__name__ + "is called"   #Contents written to log file
            with open (files,'a') as file:      #open the log file
                file.write(str+'\n')            #Write to log file
            return func(*args,**kwargs)     
        return Inner
    return Outer
@Logi()
def Hello():
    print("Hello,world,")
Hello()

Operation result:

Hellois called
27 original articles published, 45 praised, 2380 visited
Private letter follow

Tags: Python Django

Posted on Mon, 10 Feb 2020 05:37:26 -0800 by monkuar