使用slots
slots可以達(dá)到限制的目的攀圈,限制class實(shí)例能添加的屬性:
class Student(object):
__slots = ('name', 'age') # 用tuple定義允許綁定的屬性名稱
>>> s = Student()
>>> s.name = 'Michael'
>>> s.age = 25
>>> s.score = 99
Traceback (most recent call last):
File "<stdin>", line1, in <module>
AttributeError: 'Student' object has no attribute 'score'
因?yàn)?code>score沒有被放到__slots__
中岖赋,所以不能綁定score
屬性芒涡。
使用__slots__
時(shí)浮驳,__slots__
定義的屬性僅對(duì)當(dāng)前類實(shí)例起作用吁峻,對(duì)繼承的子類不起作用昼激。除非在子類也定義__slots__
。
使用@property
再綁定屬性時(shí)锡搜,若直接將屬性暴露出去橙困,會(huì)導(dǎo)致沒有辦法進(jìn)行參數(shù)檢查。如:
s = Student()
s.score = 9999 # 直接修改成績(jī)
# 為了限制scsore的范圍耕餐,通過(guò)一個(gè)set_score()方法來(lái)設(shè)置成績(jī)凡傅,通過(guò)get_score()方法獲取成績(jī)
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
# 如此,對(duì)于任意的實(shí)例進(jìn)行操作肠缔,就不能隨意更改score的值了
裝飾器(decorator)
可以給函數(shù)動(dòng)態(tài)加上功能夏跷,對(duì)于類的方法,也可以使用裝飾器明未。Python內(nèi)置的@property
裝飾器負(fù)責(zé)把一個(gè)方法編程屬性調(diào)用:
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
把一個(gè)getter
方法變成屬性槽华,只需要加上@property
就可以了,此時(shí)趟妥,@property
本身又創(chuàng)建了另一個(gè)裝飾器@score.setter
猫态,負(fù)責(zé)把一個(gè)setter
方法變成屬性賦值,于是披摄,我們就擁有一個(gè)可控的屬性操作:
>>> s = Student()
>>> s.score = 60 # OK亲雪,實(shí)際轉(zhuǎn)化為s.set_score(60)
>>> s.score # OK,實(shí)際轉(zhuǎn)化為s.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
...
ValueError: score must between 0 ~ 100!
當(dāng)不定義setter方法時(shí)疚膊,該屬性就是一個(gè)只讀屬性义辕。
小結(jié):
@property
廣泛應(yīng)用在類的定義中,可以讓調(diào)用者寫出簡(jiǎn)短的代碼寓盗,同時(shí)保證對(duì)參數(shù)進(jìn)行必要的檢查灌砖。