[Python] property - Python build-in function

property是python內建的function

Official python property: http://docs.python.org/2/library/functions.html#property

他真的...相當相當好用阿, 只是第一次看到的人可能會莫名其妙

去google也要花很多時間去了解, 或者沒看懂就不看了, 不要用就好

可是會用的話, class修改的code會有一定程度的大幅降低, 也提昇maintain的好處

舉個例來講, 我寫了一個class

class People(object):
    def __init__(self):
        self._idiom = 'Knowledge is power.'
    def _get_words(self):
        return self._idiom
    def _set_words(self, new_idiom):
        self._idiom = new_idiom

jack = People()
print 'Old:', jack._get_words()
jack._set_words('Never too old to learn.')
print 'New:', jack._get_words()

看起來很一般, 就只是設定了如何寫入(_set_words)跟讀取(_get_words)物件的資料(idiom)

如果, 今天有人繼承了你的class, 然後有使用_get_words & _set_words

結果你今天看_get_words不爽, 把他改名成_get_a_word

變成

class People(object):
    def __init__(self):
        self._idiom = 'Knowledge is power.'
    def _get_a_word(self):
        return self._idiom
    def _set_a_word(self, new_idiom):
        self._idiom = new_idiom

jack = People()
print 'Old:', jack._get_a_word()
jack._set_a_word('Never too old to learn.')
print 'New:', jack._get_a_word()

結果不管是你自己使用的程式有用到_get_words的統統都要改

或者有繼承你class的其他人, 都統統要改

不然就是變成統統不相容, 完全整個悲劇

當然你可以很快速的使用替換修改來把所有東西改掉, 但是你確定你不會遺漏?

而且使用的人還是一樣苦惱, 因為他也要全部修改

所以python property就是來幫助你不用那麼辛苦, 可以更方便的寫code, 當你的救星!!

寶傑: 友驊你說說看, 有這種可能嗎?

這...這件事全世界只有只有三個人知道, 一個是我, 一個是當事人, 一個我不能說(大誤)

其實...只要在第一次寫code的時候, 變成使用如下即可

class People(object):
    def __init__(self):
        self._idiom = 'Knowledge is power.'
    def _get_a_word(self):
        return self._idiom
    def _set_a_word(self, new_idiom):
        self._idiom = new_idiom

    idiom = property(_get_a_word, _set_a_word)

jack = People()
print 'Old:', jack.idiom
jack.idiom = 'Never too old to learn.'
print 'New:', jack.idiom

就只是在class那邊加了一行, property(_get_a_words, _set_a_words)

注意, 順序第一個是get, 第二個是set, 其實還有第三個是delete, 不過至少要有一個即可

然後後面寫code, 要操控都只要用idiom這個變數即可, 不用再去在乎說哪個get function or set function

這樣不管你改啥名稱, 只要記得用property設定好, 就不怕後續的修改維護

別人也都只要用idiom去呼叫或修改參數就好, 不用管你背後的名稱修改, 方便吧?!

那除了這方法以外, 也可以用decorator的方式去用, 如下例

class People(object):
    def __init__(self):
        self._idiom = 'Knowledge is power.'

    @property
    def idiom(self):
        return self._idiom

    @idiom.setter
    def idiom(self, new_idiom):
        self._idiom = new_idiom

jack = People()
print 'Old:', jack.idiom
jack.idiom = 'Never too old to learn.'
print 'New:', jack.idiom

仔細看改了啥, 首先不管是取值或者是設值的function name都改成了idiom名稱

也就是要用property decorator的function, 名稱要統一(這很容易忘記!!)

第一個property設定的function預設會是getter, 而且名稱idiom也是這時候binding

所以後面要設定idiom的setter, 就只要在相對應的function前面打 @idiom.setter 即可

留言

這個網誌中的熱門文章

[Linux] Linux下查詢硬體記憶體資訊 Memory Information

[Other] Chrome 重新整理所有開啟頁面

[Python] Simple Socket Server