The writing method and application scenario of Python decorator

Keywords: Programming Python Django

Application scenario:

1, 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:

from functools import wraps    # The latest python reference is import functools

def requires_auth(f):    #  f is the function we need to decorate. At first glance, it is a decorator without parameters
    @wraps(f)     # New python @ functools.wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            authenticate()
        return f(*args, **kwargs)
    return decorated    # The decorator needs to be configured to run. Here is the code interception display application

2. Logging

Log is another highlight of decorator application. Here's an example:

'''
//No one answers the questions? Xiaobian created a Python learning exchange QQ group: 579817333 
//Looking for like-minded small partners, mutual help, there are good video learning tutorials and PDF ebooks in the group!
'''
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)

I'm sure you're already thinking about another clever use of decorators.

3. Decorator with parameters

Decorators with parameters are typical closure functions

4. Embed decorator in function

Let's go back to the log example and create a wrapper function that allows us to specify a log file for output

'''
//No one answers the questions? Xiaobian created a Python learning exchange QQ group: 579817333 
//Looking for like-minded small partners, mutual help, there are good video learning tutorials and PDF ebooks in the group!
'''
from functools import wraps

def logit(logfile='out.log'):
    def logging_decorator(func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            log_string = func.__name__ + " was called"
            print(log_string)
            # Open logfile and write content
            with open(logfile, 'a') as opened_file:
                # Now type the log to the specified logfile
                opened_file.write(log_string + '\n')
            return func(*args, **kwargs)
        return wrapped_function
    return logging_decorator
@logit()
def myfunc1():
    pass

myfunc1()
# Output: myfunc1 was called
# Now a file called out.log appears, which contains the above string

@logit(logfile='func2.log')
def myfunc2():
    pass

myfunc2()
# Output: myfunc2 was called
# Now a file called func2.log appears, which contains the above string

5. Ornaments

Now we have logit decorators that can be used in formal environments, but when some parts of our application are still fragile, exceptions may be something that needs more urgent attention. For example, sometimes you just want to log to a file. Sometimes you want to send an email with a log and a record. This is a scenario using inheritance, but so far we've only seen the functions used to build the decorator.

Fortunately, classes can also be used to build decorators. Let's rebuild logit as a class instead of a function.

Posted by sgs-techie on Thu, 26 Dec 2019 06:04:40 -0800