Python全栈day28(类的装饰器)

  类是一个对象也可以像函数一样加装饰器

  类的装饰器.py

def deco(obj):
    print('======',obj)
    obj.x=1
    obj.y=2
    obj.z=3
    return obj

# @deco  #test=deco(test)
# def test():
#     print('test函数运行')


#运行了装饰器所以打印了装饰器里面的print内容 @deco #Foo=deco(Foo)
#====== class Foo: pass
#打印类的字典,其中xyz属性是在装饰器函数里面定义的 print(Foo.__dict__) #{'__doc__': None, 'z': 3, 'y': 2, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, 'x': 1, '__module__': '__main__'}

  本装饰器就是把类作为实参传递给函数deco然后把返回值赋值给Foo,在装饰器函数里面可以定义对应类的属性

  以上装饰器虽然在装饰器里面实现了对类属性进行赋值但是把赋值写死了

  下面通过嵌套把装饰器写的灵活

  类的装饰器2.py

#定义装饰器函数deco函数接受参数为字典格式
def deco(**kwargs):
    def wrapper(obj):
        print('--->',kwargs)
        #---> {'y': 2, 'z': 3, 'x': 1}
        print('类名--->',obj)
        #类名---> <class '__main__.Foo'>
        for key,val in kwargs.items():
            setattr(obj,key,val)
        return obj
    print('===>',kwargs)
    #===> {'y': 2, 'z': 3, 'x': 1}
    return wrapper
#在原装饰器deco嵌套一个内部函数wrapper
#执行步骤
#1,deco(x=1,y=2,z=3)执行函数deco返回的是函数wrapper
#2,@wrapper装饰类Foo 相当于把类Foo作为参数传递给函数wrapper然后再返回给Foo
#3,在函数wrapper内部执行对应的对类属性执行赋值操作使用了函数setattr,传递3个参数1位对象2为key3为value
@deco(x=1,y=2,z=3)  #deco(x=1,y=2,z=3) -->@wrapper
class Foo:
    pass



print(Foo.x)
#1


#同理使用装饰器装饰另外一个类可以通过在装饰的时候传递参数实现对不同类装饰的定制
@deco(name='zhangsan')
class Bar:
    pass

#装饰成功打印正确
print(Bar.name)
#zhangsan

  类的装饰器的应用.py

class Typed:
    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)
        #使用对应的key返回值
        return instance.__dict__[self.key]


    def __set__(self, instance, value):
        print('set方法')
        #instance就是实例化出来的对象本身
        # print('instance是[%s]'%instance)
        # print('value是[%s]'%value)
        #对应的key进行赋值设置操作
        if not isinstance(value,self.expected_type):
            # print('你输入是不是字符串类型,错误')
            # return
            raise TypeError('%s你传入的不是%s'%(value,self.expected_type))
        instance.__dict__[self.key] = value

    def __delete__(self, instance):
        print('delete方法')
        # print('instance是[%s]' % instance)
        #使用对应的key删除操作
        instance.__dict__.pop(self.key)

def deco(**kwargs):
    def wrapper(obj):
        for key,val in kwargs.items():
            print('=====>',key,val)
            #第一次循环key='name' val='str'
            #相当于给类加了对应的类属性设置为描述符
            #完成了之前People类里面的name = Typed('name',str)
            setattr(obj,key,Typed(key,val))
        return obj
    return wrapper

@deco(name=str,age=int)
class People:
    # name = Typed('name',str)
    # age = Typed('age',int)
    def __init__(self,name,age,salary):
        self.name = name
        self.age = age
        self.salary = salary

p1=People('zhangsan',18,999999)
print(p1.__dict__)

  把之前通过描述符实现的对类型限制的功能使用装饰器实现,简化代码

  使用装饰器来给类属性添加一个属性,只不过这个属性比较特殊,是一个描述符

转载于:https://www.cnblogs.com/minseo/p/8526782.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值