首頁 > 軟體

Python 私有屬性與私有方法

2022-03-01 19:00:49

1. 場景定義

私有屬性:

是指在 Python 的物件導向開發過程中,物件的某些屬性只想在物件的內部被使用,但不想在外部被存取到這些屬性。

即:私有屬性是物件不願意公開的屬性。

私有方法:

是指在 Python 的物件導向開發過程中,物件的某些方法或者稱為函數只想在物件的內部被使用,但不想在外部被存取到這些方法或函數。

即:私有方法是物件不願意公開的方法或函數。

2. 語法定義

在 Python 中定義私有屬性和私有方法的語法如下:

class Staff:
    def __init__(self, s_name, s_salary):
      self.s_name = s_name
      self.__salary = s_salary
      
    def __secret(self):
      print("%s 的工資是 %d" % (self.s_name, self.__salary))
  • (1). __salary是以兩個下劃線開頭來定義的私有屬性。
  • (2). __secret(self)是以兩個下劃線開頭來定義的私有方法。

3. 呼叫分析

(1). 在__init__的物件初始化方法中,以兩個下劃線開頭定義的__salary屬性就是私有屬性。

現在在物件的外部來呼叫一下__salary屬性,看是否能正常存取該私有屬性。

從上圖執行結果可以看出,第11行,即在物件外部存取物件的私有屬性 __salary 時,提示 AttributeError 錯誤,Staff 物件 zhangsan 沒有屬性 __salary。

為了證明 Staff 類物件確實是有__salary 這個範例屬性的,只是因為在物件外部不能存取私有屬性。

我把 self.__salary 修改為:self.salary__secret(self)方法對self.__salary屬性的參照,做相應的修改,看如下圖所示的執行結果。

可以從執行結果看出,這種非私有屬性在外部的呼叫是正常的,沒有提示 AttributeError 錯誤。

(2). 在__secret(self) 實體方法中,以兩個下劃線開頭定義的__secret(self)方法就是私有方法。

和上面測試流程一樣,先在物件的外部來呼叫私有方法__secret(self),看是否能正常呼叫該私有方法。

從上圖執行結果可以看出,第11行,即在物件外部存取物件的私有方法__secret(self) 時,提示 AttributeError 錯誤,Staff 物件 zhangsan 沒有 __secret 方法。

為了證明 Staff 類物件是有__secret(self)這個實體方法的,只是因為在物件外部不能存取私有方法。

我把 __secret(self) 方法修改為:secret(self),其他程式碼不變,看如下圖所示的執行結果。

可以從執行結果看出,這種非私有方法在外部的呼叫是正常的,沒有提示 AttributeError 錯誤。

(3). 從下圖可以看出,在物件內部私有方法與私有屬性是可以被呼叫的。

如圖中的 work 方法呼叫了私有方法__secret(self),而私有方法__secret(self)呼叫了私有屬性__salary。

在物件外部使用 Staff 類物件 zhangsan 來呼叫 work 方法,可以間接存取到物件的私有屬性和私有方法。

從控制檯輸出結果來看 work 方法能正常存取到物件內部定義的私有屬性和私有方法。

4. Python偽私有屬性和私有方法

在 Python 中,並沒有真正意義上的私有,因為 Python 內部在給屬性、方法命名時,對名稱做了一些特殊處理,使得外界無法存取到對應的屬性和方法。

以私有屬性和私有方法為例,Python內部處理方式為:

  • (1). 屬性: __salary,經過處理後的屬性名為:_Staff__salary(_類名__屬性名)
  • (2). 方法: __secret,經過處理後的方法名為:_Staff__secret(_類名__方法名)

知道了 Python 內部對於私有屬性和私有方法的處理,現在使用這種處理後的命名方式來在物件外部存取私有屬性和私有方法,看是否能存取正常。

class Staff:
    def __init__(self, s_name, s_salary):
        self.s_name = s_name
        self.__salary = s_salary

    def __secret(self):
        return "%s的工資是 %d" % (self.s_name, self.__salary)


zhangsan = Staff("張三", 10000)
print(zhangsan._Staff__salary)
print(zhangsan._Staff__secret())

執行結果如下圖所示:

控制檯沒有拋任何的異常,之前的提示 AttributeError 錯誤也沒有了。

這個例子證明了 Python 是沒有真正意義上的私有的,當知道了其內部處理方式後,依然可以使用_類名__屬性名(方法名)的方法來在物件外部存取到物件內部定義的私有屬性和私有方法。

但這種方式在日常工作中是不推薦使用的,既然在物件內部定義屬性和方法時,就宣告了其為私有的,呼叫方就需要遵守其規則。

到此這篇關於Python 私有屬性與私有方法的文章就介紹到這了,更多相關Python私有屬性與私有方法內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com