什麼是偽私有屬性?
在python中,沒有類似 private 之類的關鍵字來宣告私有方法或屬性。
python中要宣告私有屬性,需要在屬性前加上雙下劃線(但是結尾處不能有雙下劃線),如:self.__a。然而這樣的什麼方式並不是真正私有,而是「偽私有」。
執行以下**來驗證:
classa(object):
def__func(self):pass
if__name__ == '
__main__':
print(a.__dict__)
執行結果:
我們通過類的__dict__屬性,將class a的所有屬性列印出來,從列印的結果可以發現:原先定義的偽私有屬性(方法):__func 在__dict__中並不存在,取而代之的是_a_func這個方法,方法__func的變數名被壓縮。
如此在外部呼叫class a的__func方法時,會提示無法找到。修改**進行測試:
classa(object):
def__func(self):pass
if__name__ == '
__main__':
a =a()
a.__func()
執行後出現異常,提示a沒有屬性__func,從而實現類似私有屬性的功能。
attributeerror: 'a' object has no attribute '
__func
'
之所以說它是「偽私有」,是因為在了解偽私有變數的變數名壓縮規則後,可以根據壓縮規則進行呼叫。
再次修改**進行驗證:
classa(object):
def__func(self):print('
hello python')
if__name__ == '
__main__':
a =a()
a._a__func()
執行結果正常, 成功列印「hello python」字串。
hello python
所以,python的類並不存在正在的私有屬性,通過雙下劃線實現的偽私有屬性,本質上是對變數名進行壓縮,使之無法直接在外部呼叫。
為什麼要使用偽私有屬性
使用偽私有屬性是為了避免在類樹中,多個類賦值相同的屬性引發衝突問題。
假設有兩個類,c1 和 c2,他們都有相同的屬性x。
classc1():
defmeth1(self):
self.x = '
hello world
'def
meth2(self):
print(self.x)
c1 =c1()c1.meth1()
c1.meth2()
classc2():
defmeth3(self):
self.x = '
hello python
'def
meth4(self):
print(self.x)
c2 = c2()c2.meth3()
c2.meth4()
類c1和c2在單獨呼叫時,輸出結果沒有問題,符合預期:呼叫meth2方法時,列印meth1的賦值結果;呼叫meth4方法時,列印meth3的賦值結果。
此時增加乙個新的類c3,繼承自c1、c2(多重繼承):
classc1():
defmeth1(self):
self.x = '
hello world
'def
meth2(self):
(self.x)
class
c2():
defmeth3(self):
self.x = '
hello python
'def
meth4(self):
(self.x)
class
c3(c1, c2):
pass
c3 =c3()
c3.meth1()
c3.meth3()
c3.meth2()
c3.meth4()
從執行結果可以看出,每次 print(self.x)的內容,取決於 self.x 最後一次賦值的內容。
hello pythonhello python
在示例**中,先呼叫 c3.meth1() 進行賦值,self.x的值為「hello world」,再呼叫 c3.meth3() 進行賦值時,self.x的值被覆蓋,目前的值為「hello python」。
後續再呼叫c3.meth2()列印self.x的值時,實際上列印的是最後一次賦值結果,這在有些情況下跟類的設計初衷是相違背的:在c1中,meth2希望列印的是在meth1中賦值的內容:「hello world」。
在使用偽私有屬性後可以解決變數名self.x相互覆蓋的問題(因為self.__x 被壓縮成了 self._c1__x 和 self._c2__x,變數名不同,不會互相覆蓋):
classc1():
defmeth1(self):
self.
__x = '
hello world
'def
meth2(self):
print(self.__x
)class
c2():
defmeth3(self):
self.
__x = '
hello python
'def
meth4(self):
print(self.__x
)class
c3(c1, c2):
pass
c3 =c3()
c3.meth1()
c3.meth3()
c3.meth2()
c3.meth4()
執行結果符合c1的設計初衷:呼叫meth2時應該列印出meth1的賦值結果:
hello worldhello python
python (偽)私有屬性和私有方法
在定義屬性或方法時,在屬性名或者方法名前增加兩個下劃線,定義的就是私有屬性或方法。在實際開發中,物件的某些屬性或方法只希望在物件的內部被使用,而不希望在外部被訪問到。class person def init self,name self.name name 定義私有屬性 self.like 看蒼老...
python的偽私有
python是物件導向程式設計的,其類的私有部分實際上是偽私有,變數名即可定義私有變數 在類外雖然不能直接訪問,但是通過 類名 變數名即可訪問,例如 class ball color red 雖然是類的私有變數,但是在類外可以用dd.ball color訪問該變數 def init self,nam...
python 私有屬性和視為私有屬性
python模組中的視為私有屬性 總的來說,python中有 幾種特殊的屬性 在python模組中,我們經常會見到 x 其中後面兩種 x 是習慣上的私有變數,我們不應該在外部使用它,而是應該通過呼叫內部函式來使用,但這裡是不應該而不是不能,所以要靠我們自覺遵守這個標準,另外,在自定義模組的時候,也要...