這幾天本菜鳥在學習資料結構與演算法,學習資料結構與演算法免不了要手動實現這些資料結構與演算法。在用類定義這些物件的時候,發現老是出現帶有 _ ,__ 和__xx__ 的函式,一開始也沒怎麼在意,想著這些也學過,但是今天仔細思考一下這些用法與區別,才發現已經忘的七七八八了,就這樣好奇心逼著我去找出他們的區別。閱讀了幾篇部落格之後,本菜鳥知道了這三兄弟的區別。
1. "_" 單下劃線
Python中是不存在真正的私有方法的,但是為了實現類似於c++中的私有方法,於是就在類的方法或者屬性前加一個“_”,意味著該方法或者屬性就不應該被呼叫了。
class A(object):
def _test(self):
print("這個函式不應該通過_tset呼叫,而應該通過test呼叫")
def test(self):
return self._test()
a = A()
a._test()
a.test()
複製程式碼
結果
這個函式不應該通過_tset呼叫,而應該通過test呼叫
這個函式不應該通過_tset呼叫,而應該通過test呼叫
複製程式碼
由此可得,這個方法是能被呼叫的,但出於某種約定,我們是一般不去呼叫的。
2. “__” 雙下劃線
雙下劃線表示的是私有型別的變數,既然是私有了,那肯定就不允許子類訪問了,只允許這個類(self)自身訪問。
class A(object):
def __test(self):
print("I am test in A")
def test(self):
return self.__test()
a = A()
a.test()
複製程式碼
結果:
I am test in A
複製程式碼
返回的結果是我們預料之中的。
接著,我們給A新增一個子類,並重新定義它的__test()方法。
class B(A):
def __test(self):
print("I am test in B")
b = B()
b.test()
複製程式碼
現在,結果是這樣的:
I am test in A
複製程式碼
可見,子類B重新定義之後的__test()返回的依然是A類中的__method(),由此我們可以知道以“__"開頭的方法是不能被重寫的,只允許在內部使用
"__ xx __" 前後雙下劃線
這種方法被稱為magic methods(魔術方法),一般是系統定義名字,類似於__init__(),一般是給Python呼叫的。
class WrongMethod(object):
def __init__(self, n):
self.n = n
def __add__(self, other):
return self.n - other
def __sub__(self, other):
return self.n + other
def __str__(self):
return str(self.n)
num = WrongMethod(20)
print("num = ", num)
print("num + 10 = ", num + 10)
print("num - 10 = ", num - 10)
複製程式碼
結果
num = 20
num + 10 = 10
num - 10 = 30
複製程式碼
上面的例子就能比較好的提現出來,"__ xx __" 這種方法一般是Python呼叫的。
結論
- ”_“ 是私有的,一般不應該被呼叫
- ”__“ 是為了避免子類重寫某個函式而使用的
- ”__ xx __“ 一般是用於Python呼叫