python?@property?裝飾器使用方法
一、property的裝飾器用法
先簡單上個小栗子說明:
class property(fget=None,fset=None,fdel=None,doc=None)
fget
是用于獲取屬性值的函數(shù)fset
是用于設置屬性值的函數(shù)fdel
是用于刪除屬性值的函數(shù)doc
為屬性對象創(chuàng)建文檔字符串
使用property
可以講類的方法變成同名屬性,使用起來更加簡潔,最后實例展示
使用時建議直接用property的裝飾器用法, 比較簡潔,下面是官方示例,利用@property
裝飾方法x
將其變成名稱相同的屬性, 通過fget, fset, fdel可以控制x的讀寫刪屬性.
class C: def __init__(self): self._x = None @property def x(self): """I'm the 'x' property.""" return self._x #設置fset,注意x要與@property修飾的方法名稱相同 @x.setter #這個fset名稱沒有限制,建議與x相同 def x(self, value): self._x = value #設置fdel @x.deleter def x(self): del self._x
話不多說, 直接上例子, 在Man這個類中設置一個可讀可寫的birthYear屬性,一個可讀gender屬性,一個可讀可寫可刪的體重屬性,還有一個利用birthYear推算出的age屬性
""" @property, @*.setter""" from datetime import datetime class Man: def __init__(self, birthYear=None, gender=None, weight=None): """1.使用@property可以隱藏私有屬性,例如把'_birthYear'屬性隱藏, 把property對象birthYear作為對外的屬性""" self._birthYear = birthYear self._gender = gender self._weight = weight @property def birthYear(self): return self._birthYear @birthYear.setter def birthYear(self, value): """2.可以在setter中對屬性輸入進行限制或者其他操作""" assert not value > datetime.now().year, f'please input the right value!' self._birthYear = value @property """3.獲取年齡直接用obj.age,而不需寫成方法obj.age(), 更加自然方便""" def age(self): return datetime.now().year - self._birthYear @property def gender(self): return self._gender @property def weight(self): return self._weight @weight.setter def weight(self, value): self._weight = value @weight.deleter def weight(self): del self._weight lilei = Man(1996, 'male', 180) age = lilei.age print('Lilei今年{}歲\n'.format(age)) # 設置性別 try: lilei.gender = 'female' except: print('性別無法進行更改!\n') # 更新體重 print(f'lilei減肥前的體重:{lilei.weight}\n') lilei.weight = 200 print(f'lilei減肥后的體重:{lilei.weight}\n') print('lilei減肥失敗后一氣之下將體重信息刪了\n') del lilei.weight try: print('lilei的體重{}'.format(lilei.weight)) except: print('找不到lilei的體重信息!')
輸出結果:
Lilei今年25歲
性別無法進行更改!
lilei減肥前的體重:180
lilei減肥后的體重:200
lilei減肥失敗后一氣之下將體重信息刪了
找不到lilei的體重信息!
二、舉例說明
現(xiàn)在讓我們直觀看一下python內(nèi)置property修飾器為什么會存在,可以用來解決什么問題?
先來一個具體的例子,定義一個表示攝氏度的class
并且這個類包含一個從攝氏度轉換到華氏溫度的方法。
1.不用setter和getter方法的實現(xiàn)
# 初始版本 class Celsius: def __init__(self, temperature = 0): self.temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 # 實例化 human = Celsius() # 設置溫度 human.temperature = 37 # 獲取溫度值 print(human.temperature) # 調(diào)用內(nèi)置方法將攝氏度轉化為華氏溫度 print(human.to_fahrenheit())
輸出結果:
37
98.60000000000001
2.使用setter和getter的實現(xiàn),增加溫度值輸入的限制
但是如果現(xiàn)在有人讓human.temperature = -300
, 我們知道攝氏溫度是不可能低于-273.15的,此時需要對溫度值進行限制, 常規(guī)方法是設置一個溫度值的setter
和getter
的方法,此時溫度值存放在_temperature
中
# 更新溫度限制的版本 class Celsius: def __init__(self, temperature=0): self.set_temperature(temperature) def to_fahrenheit(self): return (self.get_temperature() * 1.8) + 32 # getter method def get_temperature(self): return self._temperature # setter method def set_temperature(self, value): if value < -273.15: raise ValueError("攝氏溫度不可能低于 -273.15 !") self._temperature = value # 實例化 human = Celsius(37) # 使用添加的getter獲取溫度值 print(human.get_temperature()) # 調(diào)用內(nèi)置方法將攝氏度轉化為華氏溫度 print(human.to_fahrenheit()) # 使用添加的setter對溫度值進行設置 human.set_temperature(-300) # Get the to_fahreheit method print(human.to_fahrenheit())
毫無疑問,在設置溫度值等于-300的時候肯定會報錯,但是這個時候你可能發(fā)現(xiàn)設置和獲取溫度值的代碼發(fā)生變化而且更復雜 并且 你需要對Celsius類的初始化函數(shù)進行更改,self.temperature = temperature
到 self.set_temperature(temperature)
, 如果現(xiàn)在是一個擁有很多屬性的類, 一個一個去進行這樣的更改是很麻煩的,而且可能會導致與這個類別相關的代碼出現(xiàn)錯誤, 有沒有更好的實現(xiàn)方式呢?這個時候就該今天的主角property裝飾器出場了
3.利用property裝飾器實現(xiàn)的版本
# 使用 @property 裝飾器版本 class Celsius: def __init__(self, temperature=0): #這里的self.temperture是下面定義的property對線 temperatue #所以你會發(fā)現(xiàn)在初始化Celsius時, 調(diào)用了temperature.setting方法 self.temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 @property def temperature(self): print("獲取溫度值...") return self._temperature @temperature.setter def temperature(self, value): print("設置溫度值...") if value < -273.15: raise ValueError("攝氏溫度不可能低于 -273.15 !") self._temperature = value # 用property的實現(xiàn)后獲取和設置溫度值與最初的版本一樣! human = Celsius() # 設置溫度 human.temperature = 37 # 獲取溫度值 print(human.temperature) # 調(diào)用內(nèi)置方法將攝氏度轉化為華氏溫度 print(human.to_fahrenheit()) #測試溫度限制功能 human.temperature = -300
輸出結果:
設置溫度值...
設置溫度值...
獲取溫度值...
37
獲取溫度值...
98.60000000000001
設置溫度值...
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
d:\2.github\python_demo\016_decorator.py in <module>
30
31 #測試溫度限制功能
---> 32 human.temperature = -300d:\2.github\python_demo\016_decorator.py in temperature(self, value)
16 print("設置溫度值...")
17 if value < -273.15:
---> 18 raise ValueError("攝氏溫度不可能低于 -273.15 !")
19 self._temperature = value
20ValueError: 攝氏溫度不可能低于 -273.15 !
可以看到此時temperature
設置有限制而且獲取和設置溫度值的代碼與初始版本一模一樣,也就是說代碼可以向后兼容
到此這篇關于python @property
裝飾器使用詳細的文章就介紹到這了,更多相關python @property 裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
opencv python在視屏上截圖功能的實現(xiàn)
OpenCV是一個基于BSD許可(開源)發(fā)行的跨平臺計算機視覺庫,可以運行在Linux、Windows、Android和Mac OS操作系統(tǒng)上。這篇文章主要介紹了opencv python在視屏上截圖,需要的朋友可以參考下2020-03-03Python手拉手教你爬取貝殼房源數(shù)據(jù)的實戰(zhàn)教程
隨著人工智能的不斷發(fā)展,機器學習這門技術也越來越重要,很多人都開啟了學習機器學習,本文就介紹了機器學習的基礎內(nèi)容,了解python爬蟲,本文給大家分享Python爬取貝殼房源數(shù)據(jù)的實戰(zhàn)教程,感興趣的朋友一起學習吧2021-05-05