@property裝飾器(學生成績、個人資訊的約束)
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
當我們想要修改一個 Student 的 scroe 屬性時,可以這麼寫:
s = Student('Bob', 59)
s.score = 60
但是也可以這麼寫:
s.score = 1000
此時score變成1000,顯然,直接給屬性賦值無法檢查分數的有效性。
如果利用兩個方法,即get_score() 和 set_score():
class Student(object):
def __init__(self, name, score):
self.name = name
self.__score = score
def get_score(self):
return self.__score
def set_score(self, score):
if score < 0 or score > 100:
raise ValueError('invalid score')
self.__score = score
這樣一來,s.set_score(1000) 就會報錯。
這種使用 get/set 方法來封裝對一個屬性的訪問在許多面向物件程式設計的語言中都很常見。
但是寫 s.get_score() 和 s.set_score() 沒有直接寫 s.score 來得直接。
有沒有兩全其美的方法?----有。
因為Python支援高階函式,在函數語言程式設計中我們介紹了裝飾器函式,可以用裝飾器函式(即@property、@score.setter)把 get/set 方法“裝飾”成屬性呼叫,例項化的物件使用屬性時,不是呼叫屬性,而是用的方法名:
class Student(object ):
def __init__(self, name, score):
self.name = name
self.__score = score
@property
def score(self):
return self.__score
@score.setter
def score(self, score):
if score < 0 or score > 100:
raise ValueError('invalid score')
self.__score = score
@property其實就是實現了getter功能;
@property.setter實現的是setter功能;
還有一個 @property.deleter實現刪除功能
現在,就可以像使用屬性一樣設定score了:
>>> s = Student('Bob', 59)
>>> s.score = 60
>>> print s.score
60
>>> s.score = 1000
Traceback (most recent call last):
...
ValueError: invalid score
以上說明對 score 賦值實際呼叫的是 set方法。
如果只實現了 @property(而沒有實現@property.setter),那麼該屬性為“只讀”屬性。
定義方法的時候 @property必須在 @property.setter之前,且二者修飾的方法名相同
附加任務:
請給Student類加一個grade屬性,根據 score 計算 A(>=80)、B、C(<60)。
class Student(object):
def __init__(self, name, score):
self.name = name
self.__score = score
@property
def score(self):
return self.__score
@score.setter
def score(self, score):
if score < 0 or score > 100:
raise ValueError('invalid score')
self.__score = score
@property
def grade(self):
if self.__score >= 80:
return 'A'
elif self.__score < 60:
return 'C'
else:
return 'B'
>>> s = Student('Bob', 59)
>>> print(s.score)
59
>>> s.score = 82
>>> print(s.score)
82
>>> print(s.grade)
A
>>> s.score = 1000
Traceback (most recent call last):
...
ValueError: invalid score
利用@property對屬性賦值進行約束!還可參考下例,個人資訊的約束:
https://blog.csdn.net/qq_41359051/article/details/82939655