5、Python之装饰器

1.什么是装饰器?

器指的是工具,可以定义成一个函数

装饰指的是为其他事物添加额外的功能

装饰器具体指的是定义一个函数,改函数是为其他函数添加额外的功能

2.为什么要有装饰器?

为程序提供扩展的可能性

5.1无参装饰器

案例:为函数添加统计时间的功能

import time
def home(name):
   time.sleep(2)
   print('welcome %s to home page' %name)
   return 123456
def outter(func):
   def wrapper(*args,**kwargs):
       start=time.time()
       res=func(*args,**kwargs)
       stop=time.time()
       print(stop-start)
       return res
   return wrapper

home=outter(home)
res=home('andy')  # res=wraaper('andy')
print(res)  #home的返回值为None,home被这个名字指向的是wrapper函数的内存地址

更推荐使用以下方式

import time

#装饰器
def timmer(func):
   def wrapper(*args,**kwargs):
       start=time.time()
       res=func(*args,**kwargs)
       stop=time.time()
       print(stop-start)
       return res
   return wrapper

@timmer # home=outter(home) 在被装饰对象正上方的单独一行写@装饰器名字
def home(name):
   time.sleep(2)
   print('welcome %s to home page' %name)
   return 123456
res=home('andy')  # res=wraaper('andy')
# print(res) #home的返回值为None,home被这个名字指向的是wrapper函数的内存地址

总结无参装饰器模板

def outter(func): 
   def wrapper(*args,**kwargs):# 1.调原函数 2.为其增加新功能
       res=func(*args,**kwargs)
       return res
   return wrapper

@outter
def index():
   print('from index')
   return 123
index()

补充知识:

from functools import wraps
def outter(func):
   @wraps(func)
   def wrapper(*args,**kwargs):
       res=func(*args,**kwargs) #res=index(1,2)
       return res
   return wrapper

@outter
def index(x,y):
   print(x,y)
   return 123
index(1,2) #wraaper(1,2)

# 手动将原函数的属性赋值给wrapper函数 可以使用 @wraps(func)代替
# 1、函数wrapper.__name__ = 原函数.__name__
# 2、函数wrapper.__doc__ = 原函数.__doc__
# wrapper.__name__ = func.__name__
# wrapper.__doc__ = func.__doc__
print(index.__name__)

5.2有参装饰器

由于语法糖@的限制,outter函数只能有一个参数,并且该参数是只用来接收被装饰对象的内存地址

def auth(db_type):
   def deco(func):
       def wrapper(*args, **kwargs):
           name = input('your name>>>: ').strip()
           pwd = input('your password>>>: ').strip()

           if db_type == 'file':
               print('基于文件的验证')
               if name == 'egon' and pwd == '123':
                   res = func(*args, **kwargs)  # index(1,2)
                   return res
               else:
                   print('user or password error')
           elif db_type == 'mysql':
               print('基于mysql的验证')
           elif db_type == 'ldap':
               print('基于ldap的验证')
           else:
               print('不支持该db_type')
       return wrapper
   return deco


@auth(db_type='file')  # @deco # index=deco(index) # index=wrapper
def index(x, y):
   print('index->>%s:%s' % (x, y))

@auth(db_type='mysql')  # @deco # home=deco(home) # home=wrapper
def home(name):
   print('home->>%s' % name)


@auth(db_type='ldap')  # 账号密码的来源是ldap
def transfer():
   print('transfer')

# index(1, 2)
# home('egon')
# transfer()

有参装饰器模板

def 有参装饰器(x,y,z):
   def outter(func):
       def wrapper(*args, **kwargs):
           res = func(*args, **kwargs)
           return res
       return wrapper
   return outter

@有参装饰器(1,y=2,z=3)
def 被装饰对象():
   pass

posted on 2022-07-04 18:27  AprilX  阅读(74)  评论(0)    收藏  举报