zoukankan      html  css  js  c++  java
  • 描述符

    描述符:

    本质是一个新式类,在这个新式类中至少实现了__get__(),set(),
    del()中的一个,也被称为描述符协议
    ?为什么是新式类?
    get()调用属性时触发
    set()为一个属性赋值时触发
    del()采用del删除属性时,触发

    描述符是干什么的:
    描述符的作用是用来代理另外一个类的属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中(init))

    ps:描述符类产生的实例进行属性操作时并不会触发三个方法的执行

    当描述符被定义成另外一个类的类属性,当该属性被调用,赋值,删除时触发描述的三个方法执行

    描述符分两种:
    数据描述符:至少实现了__get__()和__set__()
    非数据描述符:没有实现__set__()
    ?实现了set,没实现get的叫啥?
    是不是说实现set的前提是需实现get,先获得属性,再设置属性

    注意事项:
    1.描述符本身应该定义成新式类,被代理的类也应该是新式类
    2.必须把描述符定义成这个类的类属性,不能定义到构造函数中
    3.要严格遵循优先级,由高到低分别为:
    ①类属性
    ②数据描述符
    ③实例属性
    ④非数据描述符
    ⑤找不到的属性触发__getattr__

    定义成一个类的类属性,规范属性的行为

    class Typed:

    self,描述符的实例化对象,instance,使用描述符的类的实例对象,当类直接调用时为None

    owner 使用描述符的类,value实例化时传入的值

    def __init__(self,name,expected_type):
        self.name=name
        self.expected_type=expected_type
    def __get__(self, instance, owner):#为什么要owner,没用到啊
        print('get--->',instance,owner)
        if instance is None:
            return self
        return instance.__dict__[self.name]
    
    def __set__(self, instance, value):
        print('set--->',instance,value)
        if not isinstance(value,self.expected_type):#限定类型
            raise TypeError('Expected %s' %str(self.expected_type))
        instance.__dict__[self.name]=value
    def __delete__(self, instance):
        print('delete--->',instance)
        instance.__dict__.pop(self.name)
    

    class People:
    name=Typed('name',str)
    age=Typed('name',int)
    salary=Typed('name',float)
    def init(self,name,age,salary):
    self.name=name
    self.age=age
    self.salary=salary

    class Typed:
    def init(self,name,expected_type):
    self.name=name
    self.expected_type=expected_type
    def get(self, instance, owner):
    print('get--->',instance,owner)
    if instance is None:
    return self
    return instance.dict[self.name]

    def __set__(self, instance, value):
        print('set--->',instance,value)
        if not isinstance(value,self.expected_type):
            raise TypeError('Expected %s' %str(self.expected_type))
        instance.__dict__[self.name]=value
    def __delete__(self, instance):
        print('delete--->',instance)
        instance.__dict__.pop(self.name)
    

    def typeassert(**kwargs):
    def decorate(cls):
    print('类的装饰器开始运行啦------>',kwargs)
    for name,expected_type in kwargs.items():#解压赋值,
    setattr(cls,name,Typed(name,expected_type))#将描述符设置为类属性
    return cls
    return decorate

    @typeassert(name=str,age=int,salary=float) #有参:1.运行typeassert(...)返回结果是decorate,此时参数都传给kwargs 2.People=decorate(People)
    class People:
    def init(self,name,age,salary):
    self.name=name
    self.age=age
    self.salary=salary

    print(People.dict)
    p1=People('egon',18,3333.3)

  • 相关阅读:
    SpringMVC请求参数接收总结(一)
    不用 Spring Security 可否?试试这个小而美的安全框架
    @ConfigurationProperties 注解使用姿势,这一篇就够了
    Spring Aware 到底是什么?
    git rebase VS git merge? 更优雅的 git 合并方式值得拥有
    Spring Bean 生命周期之destroy——终极信仰
    面试还不知道BeanFactory和ApplicationContext的区别?
    Java设计模式学习记录-享元模式
    Java设计模式学习记录-外观模式
    Java设计模式学习记录-装饰模式
  • 原文地址:https://www.cnblogs.com/robert-zhou/p/10134032.html
Copyright © 2011-2022 走看看