Python全栈开发——装饰器

#装饰器:本质就是函数,功能就是为其他函数添加附加功能
#原则
1.不修改被修饰函数的源代码
2.不修改被修饰函数的调用方式
装饰器=高阶函数+函数嵌套+闭包
#高阶函数
定义:1.函数接收的参数是一个函数名
      2.函数的返回值是一个函数名 (满足其一即可)

#简单的装饰器
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>
原文地址:https://www.cnblogs.com/lujiacheng-Python/p/9727157.html