對比Python中_,__,xx__xx
阿新 • • 發佈:2018-12-01
對比Python中_
,__
,xx__xx
_
的含義
不應該在類的外面訪問,也不會被from M import * 匯入。 Python中不存在真正的私有方法。為了實現類似於c++中私有方法,可以在類的方法或屬性前加一個“_”單下劃線,意味著該方法或屬性不應該去呼叫,它並不屬於API。
class A: def _method(self): print('約定為不在類的外面直接呼叫這個方法,但是也可以呼叫') def method(self): return self._method() a = A() a.method() a._method()
輸出:
約定為不在類的外面直接呼叫這個方法,但是也可以呼叫 約定為不在類的外面直接呼叫這個方法,但是也可以呼叫
#類A中定義了一個_method方法,按照約定是不能在類外面直接呼叫它的
為了可以在外面使用_method方法,又定義了method方法,method方法呼叫_method方法。請看程式碼演示:
#但是加了_的方法也可以在類外面呼叫:
__
的含義:
這個雙下劃線更會造成更多混亂,但它並不是用來標識一個方法或屬性是私有的,真正作用是用來避免子類覆蓋其內容。用來解決需要唯一名稱而引起的問題,比如命名衝突/過載等.
classA: def __method(self): print('This is a method from class A') def method(self): return self.__method() class B(A): def __method(self): print('This is a method from calss B') a=A() b=B() a.method() b.method() 輸出: This is a method from class A This is a method from class A
#在類A中,__method方法其實由於name mangling技術的原因,變成了_A__method,所以在A中method方法返回的是_A__method,B作為A的子類,只重寫了__method方法,並沒有重寫method方法,所以呼叫B中的method方法時,呼叫的還是_A__method方法:
#因此,在我們建立一個以"__"兩個下劃線開始的方法時,這意味著這個方法不能被重寫,它只允許在該類的內部中使用。
在A中沒有method方法,有的只是_Amethod方法,也可以在外面直接呼叫,所以python中沒有真正的私有化,看下例:
a.__method() #如果你試圖呼叫a.__method,它還是無法執行的,就如上面所說,只可以在類的內部呼叫__method。
輸出: --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-4-b8e0b1bf4d09> in <module>() ----> 1 a.__method() AttributeError: 'A' object has no attribute '__method'
可以這樣呼叫
a._A__method() This is a method from class A
在B中重寫method
class B(A): def __method(self): print('This is a method from calss B') def method(self): return self.__method() #現在B中的method方法會呼叫_B__method方法: b=B() b.method() 輸出: This is a method from calss B
__xx__
前後雙下劃線
也叫魔術方法,就是不需要人為呼叫的方法,基本就是在特定的時間自動觸發
當你看到"this"的時,就知道不要呼叫它。為什麼?因為它的意思是它是用於Python呼叫的,如下:
例1: name = "igor" name.__len__() 輸出: 4 例2: number = 10 number.__add__(20) 輸出: 30
“xx”經常是操作符或本地函式呼叫的magic methods。在上面的例子中,提供了一種重寫類的操作符的功能。
在特殊的情況下,它只是python呼叫的hook。例如,init()函式是當物件被建立初始化時呼叫的;new()是用來建立例項。
class CrazyNumber(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 = CrazyNumber(10) print(num)# 10 print(num + 5) # 5 print(num - 20) # 30 輸出: 10 5 30
結論
- 使用oneunderline來表示該方法或屬性是私有的,不屬於API;
- 使用_justto_underlines,來避免子類的重寫;
- 當建立一個用於python呼叫或一些特殊情況時,使用two_underline;
總結:python中沒有真正的私有化,但是有一些和命名有關的約定,來讓程式設計人員處理一些需要私有化的情況。
此文參考連結: https://blog.csdn.net/m0_38063172/article/details/82179591 https://blog.csdn.net/yzl11/article/details/53792416 轉載請註明出處,謝謝。