#装饰器:本质就是函数,功能就是为其他函数添加附加功能
#原则
1.不修改被修饰函数的源代码
2.不修改被修饰函数的调用方式
装饰器=高阶函数+函数嵌套+闭包
#高阶函数
定义:1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名 (满足其一即可)
上节复习回顾补充
装饰器1
高阶函数的使用
函数的嵌套
加上返回值
加上参数
验证功能实现
user_list=[
{'name':'alex','passwd':'123'},
{'name':'linhaifeng','passwd':'123'},
{'name':'wupeiqi','passwd':'123'},
{'name':'yuanhao','passwd':'123'},
]
current_dic={'username':None,'login':False}
def auth_func(func):
def wrapper(*args,**kwargs):
if current_dic['username'] and current_dic['login']:
res = func(*args, **kwargs)
return res
username=input('用户名:').strip()
passwd=input('密码:').strip()
for user_dic in user_list:
if username == user_dic['name'] and passwd == user_dic['passwd']:
current_dic['username']=username
current_dic['login']=True
res = func(*args, **kwargs)
return res
else:
print('用户名或者密码错误')
return wrapper
@auth_func
def index():
print('欢迎来到京东主页')
@auth_func
def home(name):
print('欢迎回家%s' %name)
@auth_func
def shopping_car(name):
print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))
print('before-->',current_dic)
index()
print('after--->',current_dic)
home('产品经理')
# shopping_car('产品经理')
#简单的装饰器 import time def timer(func): def wrapper(): #*args接受元组系列 **kwargs接收字典系列 start_time=time.time() res=func() #函数嵌套 stop_time=time.time() print('All time %d' %(stop_time-start_time)) return res return wrapper @timer #相当于text=timer(text) def text(): time.sleep(3) print("end.....") text()
def list_diedai(fun): def wrapper(*args,**kwargs): #*args=(num) **kwargs={'num':4} res=fun(*args,**kwargs) #*args将接收的参数转化成列表 return res.__iter__ #**kwargs将接受的参数转化成字典 return wrapper #返回地址 @list_diedai def list1(num): return [x for x in range(int(num))] p1=list1(4) print(p1) #<method-wrapper '__iter__' of list object at 0x009D45A8> print(p1()) #<list_iterator object at 0x00A93250> p2=p1() print(p1().__next__()) # 0 print(next(p1())) # 0 print(p2.__next__()) # 0 print(next(p2)) # 1 print(next(p2)) # 2 print(p2.__next__()) # 3
#类的装饰器(进阶)
#万能参数添加器
def Type(**kwargs): print(kwargs) #{'x': 7, 'j': 9} def deco(obj): print(obj) #<class '__main__.Int'> for key,val in kwargs.items(): setattr(obj,key,val) return obj print(deco) #<function Type.<locals>.deco at 0x01760AE0> return deco @Type(x=7,j=9) class Int: pass
#装饰器应用进阶
class Type: def __init__(self,x,excepet_type): #巧妙灵活 self.x=x self.excepet_type=excepet_type def __get__(self, instance, owner): # print(instance,owner) return instance.__dict__[self.x] def __set__(self, instance, value): # print(instance,value) if type(value)!=self.excepet_type: print('%s 传入的不是 %s ,错误!!!' %(self.x,self.excepet_type)) return instance.__dict__[self.x]=value def __delete__(self, instance): instance.__dict__.pop(self.x) def Type1(**kwargs): def warpper(obj): for key,val in kwargs.items(): setattr(obj,key,Type(key,val)) return obj return warpper @Type1(name=str,age=int) #先运行Type1(name=str,age=int)函数 #得到warpper的返回值,在运行 People=warpper(People) class People: # name=Type('name',str) #描述符代理 # age=Type('age',int) def __init__(self,name,age,salary): self.name=name self.age=age self.salary=salary p=People('lujiacheng','3',5000) #age 传入的不是 <class 'int'> ,错误!!! print(p.__dict__) #{'name': 'lujiacheng', 'salary': 5000} p.name=98 #name 传入的不是 <class 'str'> ,错误!!! print(p.__dict__) #{'name': 'lujiacheng', 'salary': 5000} p.name='98' print(p.__dict__) #{name': '98', 'salary': 5000} del p.name print(p.__dict__) #{'salary': 5000}
#类装饰器
class lazyproperty: def __init__(self,fun): self.func=fun def __get__(self, instance, owner): if instance is None: return self return self.func(instance) class Room: def __init__(self,name,width,length): self.name=name self.width=width self.length=length # @property # area=property(area) @lazyproperty def area(self): return self.width*self.length r=Room('dd',45,56) print(r.area) # 2520 print(Room.area) #<__main__.lazyproperty object at 0x0072E8B0>