python 装饰器
要求: 不能修改被装饰的函数的源代码 不能修改被装饰的函数的调用方式 满足上面的两种情况下给程序增添功能 组成: < 函数+实参高阶函数+返回值高阶函数+嵌套函数+语法糖 = 装饰器 >
1.简单的函数装饰器
def login(func):
print('添加的新功能')
return func
@login ### 实际上等价于run=login(run) 返回的是run
def run(x,y):
return x+y
res=run(1,4)
print(res)
###
添加的新功能
5
2.可传参的装饰器
def login(func):
def wrapper(*args,**kwargs):
print('添加功能')
print(args)
print(kwargs)
res=func(*args,**kwargs)
return res
return wrapper
@login ###等价于 run=login(run) 返回的是wrapper函数的内存地址
def run(x,y):
return x+y
res=run(1,4)
print(res)
###
添加功能
(1, 4)
{}
5
3.更复杂的装饰器
def login(url):
def outwrapper(func):
def wrapper(*args,**kwargs):
if url=='login':
print('----login')
res=func(*args,**kwargs)
return res
return wrapper
return outwrapper
@login(url='login')##run=login(url='login')(run)
def run(x,y):
return x+y
print(run(2,4))
4.类的装饰器
理论上和函数装饰器用法一样
class Typed(object):
def __init__(self,key,expected_type):
self.key=key
self.expected_type=expected_type
def __get__(self, instance, owner):
print('get方法')
# print('instance参数【%s】' %instance)
# print('owner参数【%s】' %owner)
return instance.__dict__[self.key]
def __set__(self, instance, value):
print('set方法')
# print('instance参数【%s】' % instance)
# print('value参数【%s】' % value)
# print('====>',self)
if not isinstance(value,self.expected_type):
# print('你传入的类型不是字符串,错误')
# return
raise TypeError('%s 传入的类型不是%s' %(self.key,self.expected_type))
instance.__dict__[self.key]=value
def __delete__(self, instance):
print('delete方法')
# print('instance参数【%s】' % instance)
instance.__dict__.pop(self.key)
def deco(**kwargs): #kwargs={'name':str,'age':int}
def wrapper(obj): #obj=People
for key,val in kwargs.items():#(('name',str),('age',int))
setattr(obj,key,Typed(key,val))
# setattr(People,'name',Typed('name',str)) #People.name=Typed('name',str)
return obj
return wrapper
@deco(name=str,age=int) #@wrapper ===>People=wrapper(People)
class People(object):
name='alex'
# name=Typed('name',str)
# age=Typed('age',int)
def __init__(self,name,age,salary,gender,heigth):
self.name=name
self.age=age
self.salary=salary
# p1=People('213',13.3,13.3,'x','y')
print(People.__dict__)