類的裝飾器

裝飾可以是一個函數
class Type:
    def __init__(self,key,type):
        self.key=key
        self.type=type
    def __get__(self, instance, owner):
        pass
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        if not isinstance(value,self.type):
            raise TypeError('%s不是%s'%(value,self.type))
        else:
            instance.__dict__[self.key]=value
    def __delete__(self, instance):
        pass

def deco(**kwargs):
    def wrapper(obj):
        for key,val in kwargs.items():
            setattr(obj,key,Type(key,val))
        return obj
    return wrapper

@deco(name=str,age=int,salary=float)#@wrapper ===>People=wrapper(People)
class People:
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
p1=People("alex",18,3000.0)
print(p1.__dict__)
#p2=People('bart','18',3000)

也可以是一個類

自定製property

class Lazyproperty:
    def __init__(self,func):
        print('=====>')
        self.func=func
    def __get__(self, instance, owner):
        print('get')
        if instance is None:#當類訪問靜態屬性時instance爲None
            return self
        res= self.func(instance)
        instance.__dict__[self.func.__name__]=res  #將areal直接加進實例字典
        return res


class Room:
    def __init__(self,name,width,length):
        self.name=name
        self.width=width
        self.length=length

    @property
    def area(self):
        return self.width*self.length

    @Lazyproperty   #areal=Lazyproperty(areal)
    def areal(self):
        return self.width*self.length

r=Room('bath',10,20)
print(r.area)
print(r.areal)
print(r.__dict__) #有屬性areal但是沒有area
print(Room.area,Room.areal)

#輸出
#=====>
#200
#get
#200
#{'name': 'bath', 'width': 10, 'length': 20, 'areal': 200}
#get
#<property object at 0x000001BEA6466778> <__main__.Lazyproperty object at 0x000001BEA66FA208>

property補充

class Student:
    def __init__(self,name,age,score):
        self.name=name
        self.age=age
        self.__score=score
    @property       #不可傳入參數
    def score(self):
        return self.__score
    @score.setter
    def score(self,value):  #可以傳入參數
        if not isinstance(value,float):
            raise ValueError('請輸入正確成績')
        self.__score=value
    @score.deleter
    def score(self):
        print('delete score')
        del self.__score


a=Student('alex',18,90.0)
print(a.score)
a.score=95.0
print(a.score)
del a.score
print(a.__dict__)

發佈了51 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章