Python 類的封裝

封裝(Encapsulation)是對 object 的一種抽象,即將某些部分隱藏起來,在程序外部看不到,即無法調用(不是人用眼睛看不到那個代碼,除非用某種加密或者混淆方法,造成現實上的困難,但這不是封裝)。


要了解封裝,離不開“私有化”,就是將類或者函數中的某些屬性限制在某個區域之內,外部無法調用。

Python 中私有化的方法也比較簡單,就是在準備私有化的屬性(包括方法、數據)名字前面加雙下劃線。例如:

#!/usr/bin/env Python
# coding=utf-8
__metaclass__ = type
class ProtectMe:
    def __init__(self):
        self.me = "qiwsir"
        self.__name = "kivi"
    def __python(self):
        print "I love Python."
    def code(self):
        print "Which language do you like?"
        self.__python()
if __name__ == "__main__":
    p = ProtectMe()
    print p.me
    print p.__name

運行一下,看看效果:

$ python 21102.py
qiwsir
Traceback (most recent call last):
  File "21102.py", line 21, in <module>
    print p.__name
AttributeError: 'ProtectMe' object has no attribute '__name'

查看報錯信息,告訴我們沒有__name 那個屬性。果然隱藏了,在類的外面無法調用。再試試那個函數,可否?

if __name__ == "__main__":
    p = ProtectMe()
    p.code()
    p.__python()

修改這部分即可。其中 p.code() 的意圖是要打印出兩句話:"Which language do you like?"和"I love Python.",code() 方法和__python() 方法在同一個類中,可以調用之。後面的那個 p.__Python() 試圖調用那個私有方法。看看效果:

$ python 21102.py 
Which language do you like?
I love Python.
Traceback (most recent call last):
  File "21102.py", line 23, in <module>
    p.__python()
AttributeError: 'ProtectMe' object has no attribute '__python'

如願以償。該調用的調用了,該隱藏的隱藏了。

用上面的方法,的確做到了封裝。但是,我如果要調用那些私有屬性,怎麼辦?


可以使用 property 函數。

#!/usr/bin/env Python
# coding=utf-8
__metaclass__ = type
class ProtectMe:
    def __init__(self):
        self.me = "qiwsir"
        self.__name = "kivi"
    @property
    def name(self):
        return self.__name
if __name__ == "__main__":
    p = ProtectMe()
    print p.name

運行結果:

$ python 21102.py 
kivi

從上面可以看出,用了 @property 之後,在調用那個方法的時候,用的是 p.name 的形式,就好像在調用一個屬性一樣,跟前面 p.me 的格式相同。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章