Two kinds of experience in using Python decorator

  • 2021-12-04 19:16:14
  • OfStack

Basic use of decorators (decorative parametric functions)


def decorator(func):
    def inner(info):
        print('inner')
        func(info)
    return inner

@decorator
def show_info(info):
    print(info)

show_info('hello')

Prevent the decorator from changing the decorative function name

When decorating the function, the decorator returns the function address of inner, so the name of the function will also change show_info. __name__ will change to inner. To prevent this phenomenon, functools can be used


import functools

def decorator(func):
	@functools.wraps(func)
    def inner(info):
        print('inner')
        func(info)
    return inner

@decorator
def show_info(info):
    print(info)

show_info('hello')

This does not change the name of the decorated function

Decorator dynamic registration function

This method is embodied in the source code of app. Route () of Flask framework


class Commands(object):
    def __init__(self):
        self.cmd = {}

    def regist_cmd(self, name: str) -> None:
        def decorator(func):
            self.cmd[name] = func
            print('func:',func)
            return func
        return decorator

commands = Commands()

#  Cause s1 The value of points to the show_h Function address of 
@commands.regist_cmd('s1')
def show_h():
    print('show_h')

#  Cause s2 The value of points to the show_e Function address of 
@commands.regist_cmd('s2')
def show_e():
    print('show_e')

func = commands.cmd['s1']
func()

Personal experience

Adding (func_name) can be used when reading the decorator code
Take as an example


@commands.regist_cmd('s2')
def show_e():
    print('show_e')

That is, show_e = commands.regist_cmd ('s2') (show_e)


Related articles: