1. 程式人生 > 其它 >Python中 _xx、__xx、__xx__ 的區別

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__() 來完成構造和初始化。