Python的偽私有屬性

2022-07-12 02:30:13 字數 3218 閱讀 5143

什麼是偽私有屬性?

在python中,沒有類似 private 之類的關鍵字來宣告私有方法或屬性。

python中要宣告私有屬性,需要在屬性前加上雙下劃線(但是結尾處不能有雙下劃線),如:self.__a。然而這樣的什麼方式並不是真正私有,而是「偽私有」。

執行以下**來驗證:

class

a(object):

def__func(self):pass

if__name__ == '

__main__':

print(a.__dict__)

執行結果:

我們通過類的__dict__屬性,將class a的所有屬性列印出來,從列印的結果可以發現:原先定義的偽私有屬性(方法):__func 在__dict__中並不存在,取而代之的是_a_func這個方法,方法__func的變數名被壓縮。

如此在外部呼叫class a的__func方法時,會提示無法找到。修改**進行測試:

class

a(object):

def__func(self):pass

if__name__ == '

__main__':

a =a()

a.__func()

執行後出現異常,提示a沒有屬性__func,從而實現類似私有屬性的功能。

attributeerror: 'a

' object has no attribute '

__func

'

之所以說它是「偽私有」,是因為在了解偽私有變數的變數名壓縮規則後,可以根據壓縮規則進行呼叫。

再次修改**進行驗證:

class

a(object):

def__func(self):print('

hello python')

if__name__ == '

__main__':

a =a()

a._a__func()

執行結果正常, 成功列印「hello python」字串。

hello python

所以,python的類並不存在正在的私有屬性,通過雙下劃線實現的偽私有屬性,本質上是對變數名進行壓縮,使之無法直接在外部呼叫。

為什麼要使用偽私有屬性

使用偽私有屬性是為了避免在類樹中,多個類賦值相同的屬性引發衝突問題。

假設有兩個類,c1 和 c2,他們都有相同的屬性x。

class

c1():

defmeth1(self):

self.x = '

hello world

'def

meth2(self):

print(self.x)

c1 =c1()

c1.meth1()

c1.meth2()

class

c2():

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(多重繼承):

class

c1():

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()

從執行結果可以看出,每次 print(self.x)的內容,取決於 self.x 最後一次賦值的內容。

hello python

hello 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,變數名不同,不會互相覆蓋):

class

c1():

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 world

hello 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 是習慣上的私有變數,我們不應該在外部使用它,而是應該通過呼叫內部函式來使用,但這裡是不應該而不是不能,所以要靠我們自覺遵守這個標準,另外,在自定義模組的時候,也要...