在使用 @property
之前,讓我們先來看一個簡單的例子:
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)
>>> e.get_score()
60
>>> e.set_score(70)
>>> e.get_score()
70
在上面,我們定義了一個 Exam 類,為了避免直接對 _score
屬性操作,我們提供了 get_score 和 set_score 方法,這樣起到了封裝的作用,把一些不想對外公開的屬性隱蔽起來,而只是提供方法給用戶操作,在方法里面,我們可以檢查參數(shù)的合理性等。
這樣做沒什么問題,但是我們有更簡單的方式來做這件事,Python 提供了 property
裝飾器,被裝飾的方法,我們可以將其『當作』屬性來用,看下面的例子:
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)
>>> e.score
60
>>> e.score = 90
>>> e.score
90
>>> e.score = 200
>>> e.score
100
在上面,我們給方法 score 加上了 @property
,于是我們可以把 score 當成一個屬性來用,此時,又會創(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)
>>> e.score
60
>>> e.score = 200 # score 是只讀屬性,不能設置值
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-676-b0515304f6e0> in <module>()
----> 1 e.score = 200
AttributeError: can't set attribute
@property
把方法『變成』了屬性。