Python版本:3.5.2 假如我們有一個Student類,併在其中定義了一個score屬性,但是score屬性會被顯露出去,沒辦法檢查參數,導致成績可以隨意更改: ~~~~ stu = Student() stu.score = 9999 ~~~~ 這顯然是不合邏輯的,為了限制score的範圍, ...
Python版本:3.5.2
假如我們有一個Student類,併在其中定義了一個score屬性,但是score屬性會被顯露出去,沒辦法檢查參數,導致成績可以隨意更改:
stu = Student()
stu.score = 9999
這顯然是不合邏輯的,為了限制score的範圍,可以通過一個set_score()方法來設置成績,並通過一個get_score()方法來獲取成績,這樣的話,就可以實現參數的檢查:
class Student(object):
def get_score(self):
return self._score
def set_score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
調用及結果如下:
調用:
stu = Student()
stu.set_score(99)
print(stu.get_score())
stu.set_score(9999)
結果:
99
Traceback (most recent call last):
stu.set_score(9999)
raise ValueError('score must between 0 ~ 100!')
ValueError: score must between 0 ~ 100!
但是,上面的調用方法又略顯複雜,沒有直接用屬性那麼直接簡單。
這個問題是可以得到解決的,裝飾器可以給函數動態的加上功能,那麼對於類方法,一樣可以起作用,可以使用@property裝飾器將類方法變成屬性來調用:
class Student(object):
@property
def score(self):
return self._score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
把一個get方法變成屬性,只需要加上@property就可以,此時,@property本身又創建了另一個裝飾器@score.setter,負責把set方法也變成屬性並可以賦值,之後我們就可以直接對score進行屬性的操作並帶有參數的檢查:
調用:
stu = Student()
stu.score = 99
print(stu.score)
stu.score = 9999
結果:
99
Traceback (most recent call last):
stu.score = 9999
raise ValueError('score must between 0 ~ 100!')
ValueError: score must between 0 ~ 100!
有了這個@property,我們就可以無顧慮的操作類的屬性。
如果我們我們在類中只定義了get方法(並用@property裝飾),而沒有定義set方法,那麼這個屬性就會變成只讀屬性。
@property廣泛應用在類的定義中,可以讓調用者寫出簡短的代碼,同時保證對參數進行必要的檢查,這樣,程式運行時就減少了出錯的可能性。