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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM