Python 3.1 快速導覽 - 類別 屬性封裝

Python 類別 (class) 的屬性 (attribute) 權限預設是公開的,因此類別以外的地方也可以存取,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Demo:
    x = 0
 
    def __init__(self, i):
        self.i = i
        Demo.x += 1
     
    def __str__(self):
        return str(self.i)
          
    def hello(self):
        print("hello", self.i)
     
a = Demo(9527)
a.hello()
print("hello", a.i)
print()
print("a.i =", a.i)
print("Demo.x =", Demo.x)
 
# 《程式語言教學誌》的範例程式
# 檔名:cla15.py
# 功能:示範 Python 程式
# 作者:張凱慶
# 時間:西元 2010 年 12 月


執行結果如下



上例中第 16 行
16
print("hello", a.i)


第 18 行
18
print("a.i =", a.i)


第 19 行
18
print("Demo.x =", Demo.x)


這些類別以外的地方,直接以句點運算子存取屬性值,然而有時候我們希望做到良好的資訊隱藏 (information hiding) ,也就是說我們不要讓類別定義以外的地方,存取屬性值,這時,我們可以將屬性設定為私有的,簡單來說,就是在屬性識別字 (identifier) 名稱前加上連續兩個底線符號。


這樣一來,若是要在類別以外的地方使用屬性值,需要另外可存取的公開方法 (method) ,例如
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Demo:
    __x = 0
 
    def __init__(self, i):
        self.__i = i
        Demo.__x += 1
     
    def __str__(self):
        return str(self.__i)
          
    def hello(self):
        print("hello", self.__i)
     
    @classmethod
    def getX(cls):
        return cls.__x
 
a = Demo(9527)
a.hello()
print("Demo.__x =", Demo.getX())
 
# 《程式語言教學誌》的範例程式
# 檔名:cla16.py
# 功能:示範 Python 程式
# 作者:張凱慶
# 時間:西元 2010 年 12 月


執行結果如下



第 14 行到第 16 行,我們利用類別方法 getx() 存取類別屬性 __x
14
15
16
@classmethod
def getX(cls):
    return cls.__x


第 20 行呼叫 getx() 便可得到 __x
20
print("Demo.__x =", Demo.getX())


如果沒有用利用 getx() ,第 20 行改成
20
print("Demo.__x =", Demo.__x)


會得到以下的執行錯誤



方法預設也都是公開的,若要定義私有的方法,也就是指能在類別內呼叫的方法,同樣在方法識別字名稱前加上連續兩個底線符號,這樣的方法就變成私有的。


中英文術語對照
類別class
屬性attribute
資訊隱藏information hiding
識別字identifier
方法method






沒有留言: