python私有變量和私有方法
1. 下劃線妙用
在 Python 中,下劃線可是非常推薦使用的符號(hào):
變量名推薦使用下劃線分隔的蛇形命名法
魔法方法、構(gòu)造函數(shù)都需要使用雙下劃線
對(duì)于暫時(shí)用不到的變量值,可以賦值給單下劃線 _
進(jìn)行占位
根據(jù)分類,我把下劃線寫法分成下面五種:
單前導(dǎo)下劃線:_var
單末尾下劃線:var_
雙前導(dǎo)下劃線:__var
雙前導(dǎo)和末尾下劃線:__var__
單下劃線:_
由于篇幅所限,本篇將只介紹跟標(biāo)題(私有變量與私有方法)有關(guān)的用法,也就是訪問(wèn)控制。
上面五種寫法中,涉及到訪問(wèn)控制的有:_var
和 __var
2. 單前導(dǎo)下劃線 _var
下劃線前綴的含義是告知其他程序員:以單個(gè)下劃線開頭的變量或方法僅供內(nèi)部使用。
請(qǐng)看下面這個(gè)例子
class Demo:
def __init__(self):
self.foo = 11
self._bar = 22
如果你實(shí)例化此類,然后分別訪問(wèn) self.foo
和 self._bar
會(huì)發(fā)生什么情況?
>>> demo = Demo()
>>> demo.foo
11
>>> demo._bar
22
結(jié)果是:外界都可以直接訪問(wèn)這兩個(gè)屬性。
但實(shí)際上,二者是有區(qū)別的。PEP 8 有提及,如果一個(gè)屬性的有單前導(dǎo)下劃線,則該屬性應(yīng)該僅供內(nèi)部訪問(wèn)。
但這并不是強(qiáng)制性的,不然上面我們也不可能通過(guò) self._bar
訪問(wèn)到 22,但做為一名 Python 程序員最好遵守這一共識(shí)。
3. 雙前導(dǎo)下劃線 __var
雙下劃線前綴會(huì)導(dǎo)致Python解釋器重寫屬性名稱,以避免子類中的命名沖突。
這也叫做名稱修飾(name mangling) - 解釋器更改變量的名稱,以便在類被擴(kuò)展的時(shí)候不容易產(chǎn)生沖突。
我知道這聽起來(lái)很抽象。因此,我組合了一個(gè)小小的代碼示例來(lái)予以說(shuō)明:
class Demo:
def __init__(self):
self.foo = 11
self._bar = 22
self.__baz = 33
將其進(jìn)行實(shí)例化,然后使用 dir()
函數(shù)查看這個(gè)對(duì)象的屬性
>>> demo = Demo()
>>> dir(demo)
['_Demo__baz', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_bar', 'foo']
不難發(fā)現(xiàn),foo
和 _bar
都很正常,可以使用 demo.屬性名
進(jìn)行訪問(wèn)。
但 __baz
明顯和 foo
、 _bar
不一樣,嘗試訪問(wèn)后卻報(bào)了 AttributeError,屬性不存在。
>>> demo.__baz
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'Demo' object has no attribute '__baz'
如果你仔細(xì)觀察,你會(huì)看到此對(duì)象上有一個(gè)名為_Demo__baz
的屬性。這就是Python解釋器所做的名稱修飾。它這樣做是為了防止變量在子類中被重寫。
如果想訪問(wèn),那得按照 dir 提示的寫法去訪問(wèn),在 __baz
前面加上 _類名
。
>>> demo._Demo__baz
33
總結(jié)可得,使用雙下劃線開頭的屬性變量,就是一個(gè)私有變量。
這樣的規(guī)則在屬性上生效,在方法上也同樣適用。
如果一個(gè)實(shí)例方法,以雙下劃線開頭,那么這個(gè)方法就是一個(gè)私有的方法,不能由實(shí)例對(duì)象或者類直接調(diào)用。
必須得通過(guò) 實(shí)例._類名__方法名
來(lái)調(diào)用。
4. 總結(jié)一下
Python并沒有真正的私有化支持,但可用下劃線得到偽私有。
盡量避免定義以下劃線開頭的變量。
私有變量:以雙下劃線前導(dǎo)的變量,可以使用 實(shí)例._類名__變量名
進(jìn)行訪問(wèn)
私有方法:以雙下劃線前導(dǎo)的方法,可以使用 實(shí)例._類名__方法名()
進(jìn)行訪問(wèn)
私有變量和私有方法,雖然有辦法訪問(wèn),但是仍然不建議使用上面給出的方法直接訪問(wèn),而應(yīng)該用統(tǒng)一的接口(函數(shù)入口)來(lái)對(duì)私有變量進(jìn)行查看、變量,對(duì)私有方法進(jìn)行調(diào)用。
審核編輯:符乾江
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4260瀏覽量
62228 -
代碼
+關(guān)注
關(guān)注
30文章
4697瀏覽量
68083 -
python
+關(guān)注
關(guān)注
54文章
4758瀏覽量
84289
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論