1. 程式人生 > 其它 >Python之面向物件進階版1之prosperty裝飾器

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方法可以更改這個屬性,從外表呼叫來看就是可以訪問且可以被更改。萬變不離其宗,都是功能整合一步步搭建起來的。

參考連結:

https://zhuanlan.zhihu.com/p/165099833