通過描述符自定制@property的功能
阿新 • • 發佈:2018-08-14
由於 裝飾 int 結果 使用 屬性字典 room turn 初始
# 通過描述符自定制@property的功能 # 原始通過@property實現的功能:將類中定義的函數屬性,通過裝飾器@property將其封閉成數據屬性 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 r1= Room(‘廚房‘, 10, 4) print(r1.area) # 通過描述符與裝飾器自定制@property的功能 class Lazyproperty: # 定義描述符的類 def __init__(self, func): # 初始化時接收傳入的方法進行保存 self.func = func def __get__(self, instance, owner): if instance is None: # 解決直接用類調用屬性時傳不了實例而報錯的問題 return self res= self.func(instance) setattr(instance, self.func.__name__, res) # 將res放入實例的字典中,如果下次再調用,根據優先級實例屬性高於非數據描述符,實例的屬性字典中有就直接從實例的屬性字典中找了 return res # 返回實例對象調用父類方法的結果,instance代表實例 class Room2: def __init__(self, name, width, length): self.name = name self.width = width self.length= length @Lazyproperty # area=Lazyproperty(area) 使用裝飾器的這一步就相當於對area屬性指定了描述符,給Room2添加了一個類屬性 def area(self): return self.width * self.length r2 = Room(‘廚房‘, 10, 4) # 實例調用area print(r2.area) # 從r2中先找有沒有area屬性,沒有從父類Room2中找,找到後發現是非數據描述符,就觸發了__get__方法 # 類調用area print(Room2.area) # 由於__get__方法的接收參數需要一個實例,這裏是用類調用的,所以會傳None過去,因此會報錯
通過描述符自定制@property的功能