既要保護類的封裝特性,又要讓開發者可以使用“對象.屬性”的方式操作操作類屬性,除了使用 property() 函數,Python 還提供了 @property 裝飾器。通過 @property 裝飾器,可以直接通過方法名來訪問方法,不需要在方法名后添加一對“()”小括號。
@property 的語法格式如下:
@property def 方法名(self) 代碼塊
例如,定義一個矩形類,並定義用 @property 修飾的方法操作類中的 area 私有屬性,代碼如下:
class Rect: def __init__(self,area): self.__area = area @property def area(self): return self.__area rect = Rect(30) #直接通過方法名來訪問 area 方法 print("矩形的面積是:",rect.area)
運行結果為:
矩形的面積為: 30
上面程序中,使用 @property 修飾了 area() 方法,這樣就使得該方法變成了 area 屬性的 getter 方法。需要注意的是,如果類中只包含該方法,那么 area 屬性將是一個只讀屬性。
也就是說,在使用 Rect 類時,無法對 area 屬性重新賦值,即運行如下代碼會報錯:
rect.area = 90 print("修改后的面積:",rect.area)
運行結果為:
Traceback (most recent call last): File "C:\Users\mengma\Desktop\1.py", line 10, in <module> rect.area = 90 AttributeError: can't set attribute
而要想實現修改 area 屬性的值,還需要為 area 屬性添加 setter 方法,就需要用到 setter 裝飾器,它的語法格式如下:
@方法名.setter def 方法名(self, value): 代碼塊
例如,為 Rect 類中的 area 方法添加 setter 方法,代碼如下:
@area.setter def area(self, value): self.__area = value
再次運行如下代碼:
rect.area = 90 print("修改后的面積:",rect.area)
運行結果為:
修改后的面積: 90
這樣,area 屬性就有了 getter 和 setter 方法,該屬性就變成了具有讀寫功能的屬性。
除此之外,還可以使用 deleter 裝飾器來刪除指定屬性,其語法格式為:
@方法名.deleter def 方法名(self): 代碼塊
例如,在 Rect 類中,給 area() 方法添加 deleter 方法,實現代碼如下:
@area.deleter def area(self): self.__area = 0
然后運行如下代碼:
刪除后的area值為: 0
案例:不使用property裝飾器實現分頁
1 #利用property裝飾器實現分頁 2 3 li=[x for x in range(100)] 4 class PageBean: 5 def __init__(self,value): 6 if value.isdigit(): 7 self.page=int(value) 8 else: 9 self.page=1 10 def start(self): 11 return (self.page-1)*10 12 def end(self): 13 return self.page*10 14 while True: 15 p=input("請輸入你要查看的頁碼(退出請按0):") 16 if not(p.isdigit()): 17 print("輸入錯誤,請重新輸入") 18 else: 19 if int(p)==0: 20 break 21 else: 22 pageBean=PageBean(p) 23 liP=li[pageBean.start():pageBean.end()] 24 print(liP)
使用property裝飾器
1 #利用property裝飾器實現分頁 2 3 li=[x for x in range(100)] 4 class PageBean: 5 def __init__(self,value): 6 if value.isdigit(): 7 self.page=int(value) 8 else: 9 self.page=1 10 #使用property裝飾器進行裝飾 11 @property 12 def start(self): 13 return (self.page-1)*10 14 @property 15 def end(self): 16 return self.page*10 17 while True: 18 p=input("請輸入你要查看的頁碼(退出請按0):") 19 if not(p.isdigit()): 20 print("輸入錯誤,請重新輸入") 21 else: 22 if int(p)==0: 23 break 24 else: 25 pageBean=PageBean(p) 26 liP=li[pageBean.start:pageBean.end]#此處調用不用括號,形式上和屬性一直 27 print(liP)
