返回顶部

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)

 

posted on 2018-10-17 19:49  augustyang  阅读(1507)  评论(1编辑  收藏  举报

导航