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)

  • 相关阅读:
    生成二维码
    【C#】教你纯手工用C#实现SSH协议作为GIT服务端
    Git断点续传和离线增量更新的实现
    微信定位真的泄露了你的精确位置
    Helper Files
    正则表达式的一些应用
    Apache配置SSL实现HTTP转HTTPS及可能出现的问题(配置https启动不了的解决办法)
    Python3 采集APP数据及相关配置
    Laravel 5 中间件、路由群组、子域名路由、 权限控制的基本使用方法
    Python3使用cookielib模块
  • 原文地址:https://www.cnblogs.com/robert-zhou/p/10134032.html
Copyright © 2011-2022 走看看