Python中 _xx、__xx、__xx__ 的區別

在Python中,一般情況下我們常見的變量大都屬於公共變量,比如 xx = 13 中的 xx 就是一個公共變量,但有時候我們也會在一些Python代碼中看到一些加下劃線的變量/方法,比如 _xx__xx__xx__,我們今天就來學習下這幾個的區別。

前面有1個下劃線 _xx

如果在類中的變量/方法前面加 1 個下劃線,那麼這樣的就稱爲保護變量/方法。

class A:
    age1 = 10
    _age2 = 20

    def method_a1(self):
        print("類內部調用公共變量:{}".format(self.age1))

    def _method_a2(self):
        print("類內部調用保護變量:{}".format(self._age2))


class B(A):  # B是A的子類
    def method_b(self):
        print("子類調用父類的公共變量:{}".format(self.age1))
        print("子類調用父類的保護變量:{}".format(self._age2))


a = A()
print(a._age2)  # 通過 實例對象.保護變量 調用
print(A._age2)  # 通過 類對象.保護變量 調用

b = B()
b.method_b()
b.method_a1()  # 子類的實例對象調用父類中的公共方法
b._method_a2()  # 子類的實例對象調用父類中受保護的方法

執行結果如下:

20
20
子類調用父類的公共變量:10
子類調用父類的保護變量:20
類內部調用公共變量:10
類內部調用保護變量:20

從上面結果中可發現,當設置爲保護變量後,我們在類內部和子類也是能夠訪問到這些變量的,總的來說和公共變量沒有太大差別。我們設置爲保護變量,一般是不希望其在類的外部被使用或直接訪問。

需要注意一點,保護變量不能通過 from module import * 方式導入,但這並不意味我們在外部就無法訪問到保護變量了。

  • 如果是類內部的保護變量,我們可通過 實例對象.變量名類名.變量名 進行調用
  • 如果是類外部的保護變量,我們可先通過 import 模塊名 導入模塊,然後再通過 模塊名.變量名進行調用

前面有2個下劃線 __xx

如果在類中的變量/方法前面加 2 個下劃線,那麼這樣的就稱爲私有變量/方法,意味着只能在類內部能夠訪問到這些變量/方法,其子類也不能訪問。

然而在Python中,即使設置了私有變量/方法,如果我們真想要在外部訪問,其實也是可以實現的,具體可以通過 _類名__私有變量/方法 來進行調用。

class A:
    age1 = 10
    _age2 = 20
    __age3 = 30

    def method_a1(self):
        print("類內部調用公共變量:{}".format(self.age1))

    def _method_a2(self):
        print("類內部調用保護變量:{}".format(self._age2))

    def __method_a3(self):
        print("類內部調用私有變量:{}".format(self.__age3))


class B(A):  # B是A的子類
    def method_b(self):
        print("子類調用父類的公共變量:{}".format(self.age1))
        print("子類調用父類的保護變量:{}".format(self._age2))
        # print("子類調用父類的私有變量:{}".format(self.__age3))  # 會報錯,不能這樣調用
        print("子類調用父類的私有變量:{}".format(self._A__age3))


a = A()
# print(a.__age3)  # 會報錯,不能這樣調用
print(a._A__age3)  # 通過 實例對象._類名__私有變量 調用
# print(A.__age3)  # 會報錯,不能這樣調用
print(A._A__age3)  # 通過 類對象._類名__私有變量 調用

b = B()
b.method_b()
b.method_a1()  # 子類的實例對象調用父類中的公共方法
b._method_a2()  # 子類的實例對象調用父類中受保護的方法
# b.__method_a3()  # 會報錯,不能這樣調用
b._A__method_a3()  # 子類的實例對象調用父類中私有的方法

執行結果如下:

30
30
子類調用父類的公共變量:10
子類調用父類的保護變量:20
子類調用父類的私有變量:30
類內部調用公共變量:10
類內部調用保護變量:20
類內部調用私有變量:30

從上面可以看到,無論是保護變量還是私有變量,我們都可以在外部進行訪問,Python中並不能真正控制變量/方法的訪問權限。

  • 如果是類內部的私有變量,我們可通過 實例對象._類名__私有變量類名._類名__私有變量 進行調用
  • 如果是類外部的私有變量,我們可先通過 import 模塊名 導入模塊,然後再通過 模塊名.__私有變量進行調用

前後都有2個下劃線 __xx__

在Python中,類似 __xx____xx__() 這種前後都有 2 個下劃線的變量或方法,通常是Python中內置的特殊變量屬性或方法的標識,我們應儘量避免使用該方式來自定義變量或方法。

內置方法

一般情況下,Python代碼執行時會自動調用到這些內置屬性或方法,比如當一個類對象實例化時,就會自動調用 __new__()__init__() 來完成構造和初始化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章