淺析Python裝飾器中的@property
一、使用@property優(yōu)點
將類方法轉(zhuǎn)換為類屬性,可以用來直接獲取屬性值或者對屬性進(jìn)行賦值。
案例分析
例:
- class Exam(object):
 - def __init__(self, score):
 - self._score = score
 - def get_score(self):
 - return self._score
 - def set_score(self, val):
 - if val < 0:
 - self._score = 0
 - elif val > 100:
 - self._score = 100
 - else:
 - self._score = val
 - e = Exam(60)
 - print(e.get_score())
 - e.set_score(70)
 - print(e.get_score())
 
代碼解析:
定義了一個 Exam 類,為了避免直接對 _score 屬性操作,提供了 get_score 和 set_score 方法,這樣起到了封裝的作用,把一些不想對外公開的屬性隱蔽起來,而只是提供方法給用戶操作,在方法里面,可以檢查參數(shù)的合理性等。
Python 提供了 property 裝飾器,被裝飾的方法,可以將其『當(dāng)作』屬性來用。
例 :
- class Exam(object):
 - def __init__(self, score):
 - self._score = score
 - @property
 - def score(self):
 - return self._score
 - @score.setter
 - def score(self, val):
 - if val < 0:
 - self._score = 0
 - elif val > 100:
 - self._score = 100
 - else:
 - self._score = val
 - e = Exam(60)
 - print(e.score)
 - e.score = 90
 - print(e.score)
 - e.score = 200
 - print(e.score)
 
注:
給方法 score 加上了 @property,于是可以把 score 當(dāng)成一個屬性來用,此時,又會創(chuàng)建新的score.setter,它可以把被裝飾的方法變成屬性來賦值。
另外,也不一定要使用 score.setter 這個裝飾器,這時 score 就變成一個只讀屬性:
- class Exam(object):
 - def __init__(self, score):
 - self._score = score
 - @property
 - def score(self):
 - return self._score
 - e = Exam(60)
 - print(e.score)
 - e.score = 200 # score 是只讀屬性,不能設(shè)置值
 - print(e.score)
 
二、@property的力量
python處理上述問題的方法是使用property??梢赃@樣來實現(xiàn)它。
例 :
- class Celsius:
 - def __init__(self, temperature = 0):
 - self.temperature = temperature
 - def to_fahrenheit(self):
 - return (self.temperature * 1.8) + 32
 - def get_temperature(self):
 - print("獲得的值")
 - return self._temperature
 - def set_temperature(self, value):
 - if value < -273:
 - raise ValueError("零下273度是不可能的")
 - print("設(shè)定值")
 - self._temperature = value
 - temperature = property(get_temperature,set_temperature)
 
并且,一旦運行,在shell中發(fā)出以下代碼。
- c = Celsius()
 - print(c.temperature)
 
創(chuàng)建對象時,將調(diào)用init ()方法。此方法的線為self.temperature = temperature。
此分配自動稱為set_temperature()。
2. 屬性的作用。
任何訪問如c.temperature都會自動調(diào)用get_temperature()。
例:
- c.temperature = 37
 - print(c.temperature)
 - print(c.to_fahrenheit())
 
注:
溫度值存儲在私有變量_temperature中。temperature屬性是一個屬性對象,它提供了與此私有變量的接口。
三、深入了解property
在Python中,property()是一個內(nèi)置函數(shù),用于創(chuàng)建并返回屬性對象。
語法
- property(fget=None, fset=None, fdel=None, doc=None)
 
參數(shù)解析
fget為獲取屬性值的函數(shù),fset為設(shè)置屬性值的函數(shù),fdel為刪除屬性的函數(shù),doc為字符串(如注釋)。從實現(xiàn)中可以看出,這些函數(shù)參數(shù)是可選的。
可以簡單地按照以下方式創(chuàng)建屬性對象。
- property(fget=None, fset=None, fdel=None, doc=None)
 - print(property())
 
1. 屬性對象有三個方法,getter()、setter()和deleter()。
語法:
- temperature = property(get_temperature,set_temperature)
 
用于稍后指定fget、fset和fdel。
- # 創(chuàng)建空屬性
 - temperature = property()
 - # 設(shè)置 fget
 - temperature = temperature.getter(get_temperature)
 - # 設(shè)置 fset
 - temperature = temperature.setter(set_temperature)
 
注:
這兩段代碼是等效的。
不定義名稱get_temperature,set_temperature。
因為它們是不必要的,并且會影響類命名空間。為此,在定義getter和setter函數(shù)時重用了名稱temperature。
2. 案例
例:
- class Celsius:
 - def __init__(self, temperature = 0):
 - 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):
 - if value < -273:
 - raise ValueError("零下273度是不可能的")
 - print("零下273度是不可能的")
 - self._temperature = value
 - c=Celsius()
 - c.temperature = 37
 - print(c.temperature)
 
注:
實現(xiàn)是制作屬性的簡單方法和推薦方法。在Python中尋找屬性時,很可能會遇到這些類型的構(gòu)造。
四、總結(jié)
本文基于Python基礎(chǔ),介紹了@property 如何把方法變成了屬性。通過案例的分析,代碼的展示。介紹了@property的力量,以及提供了相應(yīng)錯誤的解決方案處理方法。屬性的作用。
歡迎大家積極嘗試,有時候看到別人實現(xiàn)起來很簡單,但是到自己動手實現(xiàn)的時候,總會有各種各樣的問題,切勿眼高手低,勤動手,才可以理解的更加深刻。
代碼很簡單,希望對你學(xué)習(xí)有幫助。























 
 
 











 
 
 
 