python中的識別符號可以包含數字、字母和_,但必須以字母或者_開頭,其中以_開頭的命名一般具有特殊的意義
單前置下劃線的名字: 《流暢的python》作者稱之為“受保護的”名字,有兩種主要的用法:
1、作為類名或函式名時, 會阻止其他python腳本通過【from module import *】陳述句匯入該名字,即該名字不會被星號匹配;
1 """foo.py模塊""" 2 def add(a, b): 3 """待匯入的函式,是個公有的名字""" 4 return a+b 5 ? 6 def _add2(a, b): 7 """待匯入的函式,是個受保護的名字""" 8 return a+b
比如,對于上面的模塊foo,如果我在另一個python腳本中使用【from foo import *】陳述句,實際上是訪問不到_add2()函式的,但是如果我使用【from foo import add, _add2】陳述句,則兩個函式都能被訪問到,
2、作為類的屬性名或方法名時 意為不希望下游的程式員直接訪問該名字,而導致意外覆寫該屬性,但是這只是一種【命名約定】,python解釋器不會對這種屬性名做特殊處理,只是表示類的定義者希望這些屬性或者方法是"私有的",但實際上并不會起任何作用,
前后均帶有雙下劃線__的命名 一般用于特殊方法的命名,用來實作物件的一些行為或者功能,比如
__new__()方法用來創建實體, __init__()方法用來初始化物件, x + y操作被映射為方法x.__add__(y),序列或者字典的索引操作x[k]映射為x.__getitem__(k), __len__()、__str__()分別被內置函式len()、str()呼叫等等,
僅開頭帶雙下劃線__的命名 用于物件的資料封裝,以此命名的屬性或者方法為類的私有屬性或者私有方法,
1 class Foo(object): 2 def __init__(self): 3 self.__name = 'private name' 4 ? 5 def getname(self): 6 return self.__name 7 ? 8 def __spam(self): 9 print 'private method' 10 ? 11 def bar(self): 12 self.__spam() 13 ?
如果在外部直接訪問私有屬性或者方法:是不可行的,這就起到了隱藏資料的作用,
1 >>> f = Foo() 2 >>> f.__name 3 ? 4 Traceback (most recent call last): 5 File "<pyshell#1>", line 1, in <module> 6 f.__name 7 AttributeError: 'Foo' object has no attribute '__name' 8 >>> f.__spam() 9 ? 10 11 Traceback (most recent call last): 12 File "<pyshell#2>", line 1, in <module> 13 f.__spam() 14 AttributeError: 'Foo' object has no attribute '__spam'
但是這種實作機制并不是很嚴格,機制是通過自動"變形"實作的,類中所有以雙下劃線開頭的名稱name都會自動變為"_類名name"的新名稱:
1 >>> f._Foo__name 2 'private name' 3 ? 4 >>> f._Foo__spam() 5 private method
這樣就可以訪問了,
這種機制可以阻止繼承類重新定義或者更改方法的實作,比如,定義一個Foo的派生類:
1 class Goo(Foo): 2 def __spam(self): 3 print 'private method of Goo'
重寫了__spam方法,運行:
1 >>> g = Goo() 2 >>> g.bar() 3 private method
呼叫bar()方法的時候依然執行的是Foo類的__spam()方法,因為在bar()方法的實作中,self.__spam()已自動變形為self._Foo__spam(),Goo繼承的bar()方法也是如此,注意此時運行的是父類中的私有化方法,而不是子類重寫的方法,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/285597.html
標籤:Python
