1. 程式人生 > >Python 面向物件 成員的訪問約束

Python 面向物件 成員的訪問約束

在Java,C++,以及PHP中都有對應的關鍵字,public,protected,private,但是在Python中卻沒有這些關鍵字來宣告類成員的訪問作用域。

在Python中,通過一套命名體系來識別成員的訪問範圍。

class MyClass(object):
    username = "python"  #變數名以字母開頭 public 
    _email = "[email protected]" #變數名以單下劃線開頭 protected 
    __tel = "18811654088" #變數名以雙下劃線開頭 private 
    def __init__(self):
        pass
從這段程式碼中可以看出一些巧妙的命名方法。
在python中所有的以字母開頭的成員名稱被python命名體系自動識別為public,

單個下劃線開頭的成員(如 _foo)被識別為protected,只有類物件和子類物件自己能訪問到這些變數,不能用“from xxx import *”而匯入;

雙下劃線開頭的成員(如__foo)被識別為private,只有類物件自己能訪問,連子類物件也不能訪問到這個資料;

以雙下劃線開頭和結尾的(__foo__)代表python裡特殊方法專用的標識,如 __init__()代表類的建構函式。

python的簡潔和優美就在於此。 

下面我們看一個例子:

class A(object):
    username = "python"  #變數名以字母開頭 public 
    _email = "[email protected]" #變數名以單下劃線開頭 protected 
    __tel = "18811654088" #變數名以雙下劃線開頭 private 
    def __init__(self):
        print 'A.__init__() is called!'
    def __func(self):#私有方法
        print "A.__func() is called!"
class B(A):
    pass
class C(B):
    pass
if __name__=='__main__':
    a=A()
    b=B()
    c=C()
    print 'A.username=',A.username #外界可訪問類的公有屬性
    print 'A._email=',A._email   #外界可訪問類的受保護的屬性
    #print A.__tel # AttributeError 類的私有屬性,外界不可訪問
    #a.__func()  #外界不可訪問私有方法
    '''類的內部定義中,所有以雙下劃線開始的名字都被‘翻譯’成前面加上單下劃線和類名的形式。
                 因此,可以像下面這樣來訪問私有屬性和私有方法。
    '''
    print 'A.__tel=',A._A__tel #可以這樣來訪問類的私有屬性
    a._A__func()    #可以這樣來呼叫私有方法
    print '--------------------------------'
    print 'B.username=',B.username #類A的公有屬性,可以通過其子類B進行訪問
    print 'B._email=',B._email  #類A的受保護的屬性,可以通過其子類B進行訪問
    #print B.__tel  #類A的私有屬性,其子類B不可訪問:AttributeError
    print 'B.__tel=',B._A__tel #可以這樣,通過類B訪問 繼承而來的私有屬性
    #b.__func() #AttributeError: 'B' object has no attribute '__func'
    b._A__func()#可以這樣,呼叫繼承而來的私有方法
    print '--------------------------------'
    print 'C.username=',C.username#類A的公有屬性,可以通過其子孫類C進行訪問
    print 'C._email=',C._email  #類A的受保護的屬性,可以通過其子孫類C進行訪問
    #print C.__tel  #類A的私有屬性,其子孫類C不可訪問:AttributeError
    print 'C.__tel=',C._A__tel #可以這樣,通過類C訪問 繼承而來的私有屬性
    #c.__func()#AttributeError: 'C' object has no attribute '__func'
    c._A__func()#可以這樣,呼叫 繼承而來的私有方法
    '''以單下劃線開始的受保護的屬性,有啥用呢?
       前面有單下劃線的名字都不會被帶星號的import語句(from module import *)匯入
    '''
執行結果:

A.__init__() is called!
A.__init__() is called!
A.__init__() is called!
A.username= python
A._email= [email protected]
A.__tel= 18811654088
A.__func() is called!
--------------------------------
B.username= python
B._email= [email protected]
B.__tel= 18811654088
A.__func() is called!
--------------------------------
C.username= python
C._email=

[email protected]
C.__tel= 18811654088
A.__func() is called!