zoukankan      html  css  js  c++  java
  • python数据描述符

    python数据描述符

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

    class Str:
        def __get__(self, instance, owner):
            print('Str调用')
        def __set__(self, instance, value):
            print('Str设置...')
        def __delete__(self, instance):
            print('Str删除...')
    
    class People:
        name=Str()
        def __init__(self,name,age): #name被Str类代理,age被Int类代理,
            self.name=name
            self.age=age

    数据描述符,对象访问顺序  依次向下

    类属性

    数据描述符:  __get__    __set__

    实例属性

    非数据描述符:  没有 __set__

    找不到属性触发 __getattr__

    描述符的应用

    class Typed:
    
        def __init__(self,key,expected_type):
            self.key = key
            self.expected_type = expected_type
    
        def __set__(self, instance, value):
            if not isinstance(value,self.expected_type):
                raise  AttributeError('%s 传入的类型不是%s' %(self.key,self.expected_type))
            instance.__dict__['self.key'] = value
    
        def __get__(self, instance, owner):
            return  instance.__dict__['self.key']
    
        def __delete__(self, instance):
            print("__delete__")
    
    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('wwwwww',2,32)
    print(p1.__dict__)
    p1.name = 'eeeee'
    print(p1.__dict__)
    print(p1.name)

    结果

    {'self.key': 2, 'salary': 32}
    {'self.key': 'eeeee', 'salary': 32}
    eeeee

    装饰器应用

    class Typed:
        def __init__(self,key,expected_type):
            self.key = key
            self.expected_type = expected_type
        def __get__(self, instance, owner):
            print('get方法')
        def __set__(self, instance, value):
            #print('set方法')
            if not isinstance(value,self.expected_type):
                raise TypeError ('%s 传入的类型不是%s' %(self.key,self.expected_type))
            instance.__dict__[self.key]=value
        def __delete__(self, instance):
            print('delete方法')
    
    def deco(**kwargs):  #kwargs={'name':str,'age':int}
        def wrapper(obj):
            for k ,v in kwargs.items():
                setattr(obj,k,Typed(k,v)) #People.name = typed('name',str)
            return obj
        return wrapper
    @deco(name
    =str,age=int,salary=float) class People: # name = Typed('name',str) # age = Typed('age',int) # salary = Typed('salary', float) def __init__(self,name,age,salary): self.name = name self.age = age self.salary = salary p = People('auh',18,12000.1) print(p.__dict__)

    @property  自己实现

    class demo:
        def __init__(self, func):
            self.func = func
            #print('==========>', func)   #<function test.area at 0x000000000220A0D0>
        def __get__(self, instance, owner):
            res = self.func(instance)
            return  res
    class test:
        def __init__(self,name,length,wide):
            self.name = name
            self.length = length
            self.wide = wide
        #@property
        @demo  #area=demo(area)
        def area(self):
            return self.length*self.wide
    
    f = test('home',1,1)
    print(f.area)
  • 相关阅读:
    Docker 容器默认root账号运行,很不安全!
    Prometheus阅读目录
    linux修改SSH远程登录端口 服务器安全篇
    linux 部署出现Fatal error: Class 'DOMDocument' not found。
    mysql开启远程访问权限
    linux 重置mysql 密码
    推送(极光推送)
    linux 搭建SVN
    C语言词频统计设计
    读《构建之法》有感
  • 原文地址:https://www.cnblogs.com/augustyang/p/9806620.html
Copyright © 2011-2022 走看看