A decorator

Knowledge 1: *args and **kwargs

def index(x,y): print(x,y) def wrapper(*args,**kwargs): Index (*args,**kwargs) wrapper(1,2,3,4,5,a=1,b=2) # pass the wrapper argument to index() 123456Copy the code

Reserve knowledge 2: Namespaces and scopes

The "nested" relationship of namespaces is determined in the function definition phase when the syntax is checkedCopy the code

Lesson 3: Function objects

Def index(): pass def foo(function): Return function foo(index) # returns foo with the memory address of index, and foo with a function 12345678Copy the code

Lesson 4: Nested definitions of functions

def outter(function):
    def wrapper():
        pass
    return wrapper
1234
Copy the code

Tip 5: Closure functions

Def outter(): x=111 def wrapper(): Print (x) return wrapper func = outter() func() # func outter() 12345678910Copy the code
1. What are decorators
  • A generator is a tool, and most scenarios are defined as functions
  • To decorate means to add something extra to something else
  • Summary: Decorators define a function or class that adds additional functionality to other functions or classes
2. Why decorators
  • Open and closed principle
    • Open: Refers to being open to expanded functionality
    • Closed: Means that the source code is closed to modification
    • That is, without modifying the source code and the way to expand the function
3. Case of decorator
No parameter decorator instance
#! /usr/bin/env python3 # -* -coding: utF-8 -* -import time from functools import wraps # Def timmer(func) def timmer(func) def timmer(func) def timmer(func) @wraps(func) # wrap the wrapper(*args, **kwargs): Start = time.time() res = func(*args, **kwargs) stop = time.time() print(' {} second '. Format (int(stop-start))) # Masquerade the return value of the function return res # Masquerade the function name # wrapper.__name__ = func.__name__ # Masquerade the function document information # Wrapper.__doc__ = func.__doc__ return wrapper @timmer # Def index = timmer(index) def index(x, y): Time. Sleep (2) print(x, y) @timmer # def other = timmer(other) def other(name): Print ('{} from other'. Format (name)) index(200, 300) print('{} \n ' {} 'format (index) __name__, index. __doc__)) other (' message') print (' function name: {} \ n function document information: {}'.format(other.__name__, other.__doc__)) 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354Copy the code

Parameterized decorator instance

Why you need a parameter-decorator:

Because of the syntax sugar @, a decorator can take only one parameter, and that parameter is used to receive the memory address of the decorator object.

When the wrapper needs additional parameters, it needs to be decorated with a parameter decorator. Arguments refer to arguments to the Wrapper, not the original function.

#! /usr/bin/env python3 # -* -coding: utF-8 -*- "" "" From functools import wraps import Pymysql def auth(dt_type): Def wraps(function) : @wraps(function) def wrapper(*args, **kwargs) usn = input('your username >>> ').strip() pwd = input('your password >>> ').strip() if dt_type == 'file': print('login from file') with open('data/user', 'rt', encoding='utf-8') as f: for line in f: username, passwords = line.strip().split() if usn == username and pwd == passwords: res = function(*args, **kwargs) return res else: print('username or password error! ') elif dt_type == 'mysql': Print ('login from mysql') db = pymysql.connect(user='root',password='1234',host='127.0.0.1', database='user',port=3306,charset='utf-8') cursor = db.cursor() data = cursor.fetchall() for line in data: username, passwords = line.strip().split() if usn == username and pwd == passwords: res = function(*args, **kwargs) return res else: print('username or password error! ') else: print('path error! ') return wrapper return deco @auth(dt_type='file') def index(x, y): "" "be decorative function "" "print (' the from index - > ', x, y) @ auth (dt_type = 'mysql') def other (x, y) : "" "be decorative function "" "print (' the from other - > ', x, y) index (1, 2) the other (3, 4) 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646 56667686970Copy the code

As you can see, a parameterized decorator is one more closure on the original decorator that is passed to the original decorator via syntactic sugar.

When multiple decorators are used at the same time, decorators are loaded from bottom up and run from top down

@deco1 @deco2 @deco3(x=1) def index(): Pass # load order # @ deco3 (x = 1) -- - > @ deco2 - > @ # deco1 run order # @ deco1 - > @ deco2 - > @ deco3 (x = 1)Copy the code

Well, that’s all for today’s sharing. If you’re interested in Python, join us.Python Learning communicationSkirt 】, receive free learning materials and source code.