Python之面向物件進階版1之prosperty裝飾器
開始Python的複習!(以前學的忘了好多-_-)
主要參考的是Github上的一個專案:https://github.com/jackfrued/Python-100-Days
文章主要是對該專案中的內容進行學習 穿插一點自己的學習想法等內容~
@property裝飾器
在之前面向物件的介紹中提到,一般不建議將屬性設為私有,這樣會給子類訪問帶來麻煩。但直接暴露又會有一系列問題,例如無法檢查賦給屬性的值是否有效。有一種解決辦法是將屬性命名以單下劃線開頭,通過這種方式來暗示屬性是受保護的,不建議外界直接訪問。(但是,這種方式防君子不防小人,如果知道命名規則一樣可以被訪問)
那君子的訪問方式是怎麼樣的呢?可以通過屬性的getter(訪問器)和setter(修改器)方法進行對應的操作。如果要做到這一點,可以考慮使用@property裝飾器來包裝這兩個方法,使得對屬性的訪問既安全又方便。
什麼是裝飾器?裝飾器從字面上來將就是修飾事物,在python中的作用就是讓一個已經存在的函式擁有一個以前沒有的功能。本質上還是一個函式,功能是為其它函式新增新功能。
裝飾器設計的原則:不改動被裝飾函式的原始碼和不改動被修飾函式的呼叫方式。
簡單來講就是一個可以給別的函式新增新功能的高階函式(可以接受函式為引數或返回一個函式的函式就是高階函式) + 巢狀函式
感覺就像PPT母版上加一個圖示,這一版式對應的就都有一樣。裝飾器就相當於以你要修飾的函式作為引數傳入,在其中又加了一個子函式用以實現要增加的功能,然後再呼叫原來的函式。從而保證在原來功能的基礎上,做了一些修飾。這樣呼叫很方便,不需要在每個函式原始碼中都增加對應的功能。(所謂整合)
def add_log(func): def wrapper(*args, **kwargs): print('增加日誌功能:') #要加的功能函式 func(*args, **kwargs) # 要修飾的函式 return wrapper @add_log def f1(name): print('普通函式 %s' % name) @add_log def f2(name, age): print('我是%s,我%s歲了' % (name, age)) f1('python') f2('java', 10)
上邊這段程式碼是參考連結中的例子。目前水平不夠還看不出來哪裡有問題....(如果有人知道的話,歡迎告知!!)
那麼property這個裝飾器究竟可以實現什麼功能呢?(簡言之就是將訪問屬性轉化為呼叫方法)
修改器setter方法可以實現更改屬性的功能。
class Person(object):
def __init__(self, name, age):
self._name = name
self._age = age
# 訪問器 - getter方法
@property
def name(self):
return self._name
# 訪問器 - getter方法
@property
def age(self):
return self._age
# 修改器 - setter方法
@age.setter
def age(self, age):
self._age = age
def play(self):
if self._age <= 16:
print('%s正在玩飛行棋.' % self._name)
else:
print('%s正在玩鬥地主.' % self._name)
def main():
person = Person('王大錘', 12)
person.play()
person.age = 22
person.play()
# person.name = '白元芳' # AttributeError: can't set attribute
if __name__ == '__main__':
main()
在上文這個例子中有一個age屬性可以被訪問,還有一個age方法可以更改這個屬性,從外表呼叫來看就是可以訪問且可以被更改。萬變不離其宗,都是功能整合一步步搭建起來的。