python:装饰器(一)

#装饰器

def decorator(obj):
    def wrapper(*args,**kwargs):
        '''
        函数里面可以操作自己想加入的功能;
        加上*args,**kwargs两个参数,即表示:
        无论被修饰的函数/类有几个参数、什么类型,都可以用该装饰器装饰,
        如果,没有写这两个参数,那就必须被装饰的函数/类有
        几个参数,装饰器就写死为几个参数;就达不到想要的效果
        '''
        print("执行装饰器")
        res=obj(*args,**kwargs)
        return res
    return wrapper

#装饰器可装饰函数:
@decorator
def add(x,y):
    return x+y

#装饰器可装饰类:
@decorator
class Math:
    def __init__(self,x,y,z):
        self.x=x
        self.y=y
        self.z=z

    def shengfa(self):
        return self.x * self.y * self.z



if __name__ == '__main__':
    a=add(2,3)
    print(a)
    m=Math(1,2,3)
    print(m.shengfa())
#描述符  +  装饰器   应用于类class,描述符用来限制参数类型,装饰器用来给类添加属性
#众所周知,python是弱类型的语言;但是,很多时候,我们在class实例化传参时,
# 需要限定不同的参数用不同的数据类型;这个时候就需要描述符的应用来代理要描述的参数
#描述符指:一个类,中重写了__get__()、__set__()、__delete__()方法中的一个,
# 但是,数据描述符都必须将三个函数重写;功能也要自己添加

class Typed():
    def __init__(self,key,type):
        '''
        :param key: 描述的属性关键字
        :param type: 所描述的属性期待的数据类型
        '''
        self.key=key
        self.type=type

    def __set__(self, instance, value):
        '''
        注释:这个函数的参数是默认的;
        instance  ;实例对象本身,
          value  :描述的对象的属性的值\即实例化的传参值
        '''
        #为了实现需求:限制传入参数的类型,这里采用if语句
        if not isinstance(value,self.type):
            raise TypeError("参数类型错误,%s的类型不是%s"%(self.key,self.type))
            #抛出异常,你也可以不抛出异常,直接print
        else:
            instance.__dict__[self.key]=value
    def __get__(self, instance, owner):
        '''
        注释:这个函数的参数是默认的;
        instance  ;实例对象本身,
        owner  :描述的对象的所属的类
        '''
        return instance.__dict__[self.key]
    def __delete__(self, instance):
        '''
        注释:这个函数的参数是默认的;
        instance  ;实例对象本身
        '''
        instance.__dict__.pop(self.key)

#上面实现了数据描述符的编写,下面举例使用描述符
#结合:装饰器+描述符

def decorator(*args,**kwargs):
    def wrapper(obj):
        for key,type in kwargs.items():#将字典转换称元祖对:(key,type)
            setattr(obj,key,Typed(key,type))#利用描述符添加属性,描述符主要限制类型;
        return obj
    return wrapper

@decorator(name=str,age=int,gender=str)
class People:
    '''
    总的来说:描述符描述属性,就是绕了一个弯,
    调用了描述符类的__get__()、__set__()、__delete__()方法,
    而不是在类自身的方法;
    这样可以实现,参数类型的限制
    '''

    # 利用描述符代理属性,当People实例化时,就会触发Typed()实例化,
    # 同时,触发__set__(),传入属性值在dict属性字典中;
    # 在调用People实例对象的name\age属性时,会触发Typed()的__get__()方法
    def __init__(self,name,age):
        self.name=name
        self.age=age


if __name__ == '__main__':
    people=People("张三",18)#不会报错
    print(people.name)
    print(People.__dict__)
    print(people.__dict__)
    # people1=People(12,"张三")#会报错

装饰器的写法不一;按照需求来写;

猜你喜欢

转载自blog.csdn.net/ak739105231/article/details/86631353
今日推荐