【Python】單下劃線與雙下劃線的區別
Python 用下劃線作為字首和字尾指定特殊變數和定義方法,主要有如下四種形式:
l 單下劃線( _ )
l 名稱前的單下劃線(如: _name )
l 名稱前的雙下劃線(如: __name )
l 名稱前後的雙下劃線(如 :__init__ )
(一) 單下劃線( _ )
只有單 下 劃線的情況,主要有兩種使用場景:
1 、在互動式直譯器中,單下劃線“ _ ”代表的是上一條執行語句的結果。如果單下劃線前面沒有語句執行, 那麼 互動式直譯器將會報單下劃線沒有定義的錯誤。也可以對單下劃線進行賦值操作,這時單下劃線代表賦值的結果。但是一般不建議對單下劃線進行賦值操作,因為單下劃線內建識別符號。
>>> _
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
_
NameError: name '_' is not defined
>>> "python"
'python'
>>> _
'python'
>>> _="Java"
>>> _
'Java'
>>>
2 、單下劃線“ _ ”還可以作為特殊的臨時變數。如果一個變數在後面不會再用到,並且不想給這個變數定義名稱, 那麼 這時就可以用單下劃線作為臨時性的變數。 例如, 對 for 迴圈語句遍歷的結果元素並不感興趣,此時就可以用單下劃線表示。
# _ 這個變數在後面不會用到
for _ in range(5):
print("Python")
(二) 名稱前的單下劃線(如: _name )
當在屬性和方法前面加上單下劃線 “ _ ”,用於指定屬性和方法是“私有”的。但是 Python 不像 Java 一樣具有私有屬性、方法、類,在屬性和方法之前加單下劃線,只是代表該屬性、方法、類只能在內部使用,是 API 中非公開的部分。如果用 from <module> import * 和 from <package> import * 時,這些屬性、方法、類將不被匯入。
# Test.py 檔案
# 普通屬性
value="Java"
# 單下劃線屬性
_otherValue="Python"
# 普通方法
def method():
print(" 我是普通方法 ")
# 單下劃線方法
def _otherMethod():
print(" 我是單下劃線方法 ")
# 普通類
class PClass(object):
def __init__(self):
print(" 普通類的初始化 ")
# 單下劃線類
class _WClass(object):
def __init__(self):
print(" 單下劃線類的初始化 ")
將上述的 Test.py 檔案匯入,進行測試。
>>> from Test import *
>>> value
'Java'
>>> _otherValue
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
_otherValue
NameError: name '_otherValue' is not defined
>>> method()
我是普通方法
>>> _otherMethod()
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
_otherMethod()
NameError: name '_otherMethod' is not defined
>>> p=PClass()
普通類的初始化
>>> w=_WClass()
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
w=_WClass()
NameError: name '_WClass' is not defined
從上面的結果可以看出,不管是屬性、方法和類,只要 在 名稱前面加了單下劃線,都不能匯出。如果對程式 Test.py 進行修改,在 檔案 開頭加入 __all__ , 結果會是如何?
# 將普通屬性、單下劃線的屬性、方法、和類加入 __all__ 列表
__all__=["value" , "_otherValue","_otherMethod","_WClass"]
修改後繼續測試:
>>> from Test import *
>>> value
'Java'
>>> _otherValue
'Python'
>>> method()
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
method()
NameError: name 'method' is not defined
>>> _otherMethod()
我是單下劃線方法
>>> p=PClass()
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
p=PClass()
NameError: name 'PClass' is not defined
>>> w= _WClass()
單下劃線類的初始化
__all__ 是一個字串列表,不管是普通的還是單下劃線的屬性、方法和類,都將匯出來,使用其他不在這個字元列表上的屬性、方法和類,都會報未定義的錯誤。不管是屬性、方法和類,只要名稱前面加了單下劃線,都不能匯入。除非是模組或包中的“ __all__ ”列表顯式地包含了它們。
(三) 名稱前的雙下劃線(如: __name )
先看看下面的程式:
class Method(object):
# 構造器方法
def __init__(self, name):
# 雙下劃線屬性
self.__name = name
# 普通方法
def sayhello(self):
print("Method say hello!")
# 雙下劃線方法
def __sayhi(self):
print("Method say hi!")
# 初始化 Method
m = Method("Python")
# 呼叫 sayhello 方法
m.sayhello()
# 呼叫 sayhi 方法
m.__sayhi()
# 輸出屬性 __name
print(m.__name)
上面的程式定義了一個類,這個類有三個方法,一個構造器方法,一個普通方法,一個雙下劃線方法,以及包括一個雙下劃線的屬性。上面 的 輸出結果 是 :
Method say hello!
Traceback (most recent call last):
File "<encoding error>", line 18, in <module>
AttributeError: 'Method' object has no attribute '__sayhi'
實際上,當物件呼叫 __sayhi() 方法時,將會報 Method 類沒有這個方法屬性的錯誤。那如何去呼叫以雙下劃線開頭的方法和屬性? Python 這樣設計的目的是什麼?
首先回答第一個問題,讀者看完下面的程式就知道怎麼呼叫了。
class Method(object):
def __init__(self, name):
self.__name = name
def sayhello(self):
print("Method say hello!")
def __sayhi(self):
print("Method say hi!")
# 初始化 Method
m = Method("Python")
# 呼叫 sayhello 方法
m.sayhello()
# 呼叫 sayhi 方法
#m.__sayhi()
m._Method__sayhi()
# 輸出屬性 __name
#print(m.__name)
print(m._Method__name)
輸出結果如下:
Method say hello!
Method say hi!
Python
從上面的程式中可以很清楚的看到,如果要呼叫以雙下劃線開頭的方法和屬性,只要以 “ _ 類名 __ 方法(屬性)”的形式就可以實現方法或者屬性的訪問了。類前面是單下劃線,類名後面是雙下劃線,然後再加上方法或者屬性。但是並不建議呼叫,因為這是 Python 內部進行呼叫的形式。
回答完第一個問題,我們看看第二個問題, Python 這樣設計的目的是什麼?
有很多人認為, Python 以雙下劃線開頭的方法和屬性表示私有的方法和屬性,實際上這樣的理解不太準確,也不能說完全錯誤的。但是這並不是 Python 設計的目的和初衷,我們先看看下面一段程式和程式執行結果 :
class AMethod(object):
def __method(self):
print("__method in class Amethod!")
def method(self):
self.__method()
print("anthod method in class AMethod!")
class BMethod(AMethod):
def __method(self):
print("__method in class Bmethod!")
if __name__=="__main__":
print(" 呼叫 AMethod 的 method 方法 ")
a = AMethod()
a.method()
print(" 呼叫 BMethod 的 method 方法 ")
b = BMethod()
b.method()
上面的程式定義了兩個類,一個是 AMethod 類,另外一個是繼承了 AMethod 類的 BMethod 類。在 AMethod 類中,定義了兩個方法,一個是以雙下劃線開頭的 __method 方法,另外一個是普通方法。在 BMethod 類中,重寫了 AMethod 類中的 __method 方法。
程式執行結果:
呼叫 AMethod 的 method 方法
__method in class Amethod!
anthod method in class AMethod!
呼叫 BMethod 的 method 方法
__method in class Amethod!
anthod method in class AMethod!
執行結果並不是我們想要的結果, b.method() 並沒有呼叫 BMethod 類的 __method 方法,而這個設計的實際目的是為了避免父類的方法被子類輕易的覆蓋。
(四) 名稱前後的雙下劃線(如 : __init__ )
在 Python 類中,可以常常看到類似於“ __init__ ”的方法,這表示在 Python 內部呼叫的方法,一般不建議在程式中呼叫。比如,當呼叫 len() 方法時,實際上呼叫了 Python 中內部的 __len__ 方法,雖然不建議呼叫這種以雙下劃線開頭以及結尾的方法,但是可以對這些方法進行重寫。比如下面的例子:
class Number(object):
def __init__(self, number):
self.number = number
def __add__(self, number):
# 重寫方法,返回兩個數的差值
return self.number - number
def __sub__(self, number):
# 重寫方法,返回兩個數的和
return self.number + number
def __str__(self):
# 重寫方法,返回字串
return str(self.number)
num = Number(100)
print(num) # 100 呼叫了 __str__ 方法
print(num+50) # 50 + 呼叫了 __add__ 方法
print(num-20) # 120 - 呼叫了 __sub__ 方法
相信看了上面所有對 Python 中下劃線作用的講解,完全能夠理解上述四種下劃線所表示的意義。最後將對上面的,進行總結。
(五) 總結
l 單下劃線( _ ) : 在互動直譯器中,表示上一條語句執行輸出的結果。另外,單下劃線還可以作為特殊的臨時變數,表示在後面將不會在用到這個變數。
l 名稱前的單下劃線:只能在內部使用,是 API 中非公開的部分,不能被 <module>import * 和 from <package> import * 匯入程式中,除非在 __all__ 列表中包含了以單下劃線開頭的屬性、方法以及類。
l 名稱前的雙下劃線:以雙下劃線開頭的屬性、方法表示避免父類的屬性和方法被子類輕易的覆蓋,一般不建議這樣定義屬性和方法,除非你自己將要做什麼。
l 名稱前後的雙下劃線:這類方法是 Python 內部定義的方法,可以重寫這些方法,這樣 Python 就可以呼叫這個重寫的方法以及利用運算子。
About Me
........................................................................................................................ ● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除 ● 本文在itpub( http://blog.itpub.net/26736162 )、部落格園( http://www.cnblogs.com/lhrbest )和個人weixin公眾號( xiaomaimiaolhr )上有同步更新 ● 本文itpub地址: http://blog.itpub.net/26736162 ● 本文部落格園地址: http://www.cnblogs.com/lhrbest ● 本文pdf版、個人簡介及小麥苗雲盤地址: http://blog.itpub.net/26736162/viewspace-1624453/ ● 資料庫筆試面試題庫及解答: http://blog.itpub.net/26736162/viewspace-2134706/ ● DBA寶典今日頭條號地址: ........................................................................................................................ ● QQ群號: 230161599 (滿) 、618766405 ● weixin群:可加我weixin,我拉大家進群,非誠勿擾 ● 聯絡我請加QQ好友 ( 646634621 ) ,註明新增緣由 ● 於 2019-01-01 06:00 ~ 2019-01-31 24:00 在魔都完成 ● 最新修改時間:2019-01-01 06:00 ~ 2019-01-31 24:00 ● 文章內容來源於小麥苗的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解 ● 版權所有,歡迎分享本文,轉載請保留出處 ........................................................................................................................ ● 小麥苗的微店 : ● 小麥苗出版的資料庫類叢書 : http://blog.itpub.net/26736162/viewspace-2142121/ ● 小麥苗OCP、OCM、高可用網路班 : http://blog.itpub.net/26736162/viewspace-2148098/ ● 小麥苗騰訊課堂主頁 : https://lhr.ke.qq.com/ ........................................................................................................................ 使用 weixin客戶端 掃描下面的二維碼來關注小麥苗的weixin公眾號( xiaomaimiaolhr )及QQ群(DBA寶典)、新增小麥苗weixin, 學習最實用的資料庫技術。
........................................................................................................................ |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2564637/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python 中的單下劃線和雙下劃線Python
- Python知識點-單雙下劃線Python
- python雙下劃線有什麼用Python
- Python中的下劃線Python
- Python下劃線用法Python
- 詳解Python中的下劃線Python
- 下劃線的學習3
- python中雙下劃線開頭得函式和變數Python函式變數
- Python 中 5 種下劃線的含義Python
- 簡單介紹Go 中的空白識別符號下劃線Go符號
- Mac 下 IDLE Python 打不開來下劃線MacPython
- python中那些雙下劃線開頭得函式和變數Python函式變數
- Java - 駝峰轉下劃線Java
- CSS 類名的單詞連字元:下劃線還是連線符?CSS字元
- Python 的類的下劃線命名有什麼不同?Python
- BGP線路與雙IP智慧雙線的區別——VecloudCloud
- 那些年走過下劃線的坑
- Python 數值中的下劃線是怎麼回事?Python
- flutterText 文字下有黃色下劃線Flutter
- python 類 預設方法有兩個下劃線Python
- python any,call,init,下劃線知識彙總Python
- CSS動畫:有活力的連結下劃線CSS動畫
- win10如何取消輸入紅色下劃線_win10word取消紅色下劃線Win10
- idea themeleaf紅色下劃線Idea
- android更改EditText下劃線顏色Android
- word空格處不顯示下劃線
- 網頁中新增下劃線樣式的方法網頁
- html中a標籤的下劃線怎麼去掉HTML
- Python中下劃線用法Python
- Python中帶下劃線_的變數和函式命名的用法Python變數函式
- Word下劃線不顯示解決方法
- CSS 控制 input 只顯示下劃線效果CSS
- excel操作下劃線轉駝峰 文字拼接Excel
- 正則關於特殊字元下劃線_的 校驗字元
- 關於 線性規劃 非線性規劃 與 凸優化優化
- SVG導航下劃線游標跟隨效果SVG
- 實現Word下劃線離文字遠點兒
- 一文看懂,單線、雙線、三線以及BGP有什麼區別