Python 面向物件 成員的訪問約束
阿新 • • 發佈:2019-01-02
在Java,C++,以及PHP中都有對應的關鍵字,public,protected,private,但是在Python中卻沒有這些關鍵字來宣告類成員的訪問作用域。
在python中所有的以字母開頭的成員名稱被python命名體系自動識別為public,
在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!