單下劃線與雙下劃線的區別

內容目錄

單下劃線與雙下劃線的區別單下劃線(_)名稱前的單下劃線(如:_name)名稱前的雙下劃線(如:__name)名稱先後的雙下劃線(如:_ init _)總結python

單下劃線與雙下劃線的區別

​ Python用下劃線做爲前綴和後綴指定特殊變量和定義方法,主要有以下四種形式:面試

  • 單下劃線(_)
  • 名稱前的單下劃線(如:_name)
  • 名稱前的雙下劃線(如:__name)
  • 名稱先後的雙下劃線(如:_ init _

單下劃線(_)

​ 只有單劃線的狀況,主要有兩種使用場景:shell

​ 一、在交互式解釋器中,單下劃線「_」表明的是上一條執行語句的結果。若是單下劃線前面沒有語句執行,交互式解釋器將會報單下劃線沒有定義的錯誤。也能夠對單下劃線進行賦值操做,這時單下劃線表明賦值的結果。可是通常不建議對單下劃線進行賦值操做,由於單下劃線內建標識符。數據庫

 1>>> _
2Traceback (most recent call last):
3  File "<pyshell#0>", line 1in <module>
4    _
5NameError: name '_' is not defined
6>>> "python"
7'python'
8>>> _
9'python'
10>>> _="Java"
11>>> _
12'Java'
13>>> 

二、單下劃線「_」還能夠做爲特殊的臨時變量。若是一個變量在後面不會再用到,而且不想給這個變量定義名稱,這時就能夠用單下劃線做爲臨時性的變量。好比對for循環語句遍歷的結果元素並不感興趣,此時就能夠用單下劃線表示。網絡

1# _ 這個變量在後面不會用到
2for _ in range(5):
3    print("Python")

名稱前的單下劃線(如:_name)

​ 當在屬性和方法前面加上單下劃線「_」,用於指定屬性和方法是「私有」的。可是Python不像Java同樣具備私有屬性、方法、類,在屬性和方法以前加單下劃線,只是表明該屬性、方法、類只能在內部使用,是API中非公開的部分。若是用from import * 和 from import * 時,這些屬性、方法、類將不被導入。app

 1# Test.py 文件
2
3#普通屬性
4value="Java"
5
6#單下劃線屬性
7_otherValue="Python"
8
9
10#普通方法
11def  method():
12    print("我是普通方法")
13
14#單下劃線方法
15def _otherMethod():
16    print("我是單下劃線方法")
17
18#普通類
19class PClass(object):
20
21    def __init__(self):
22        print("普通類的初始化")
23
24#單下劃線類
25class _WClass(object):
26
27    def __init__(self):
28        print("單下劃線類的初始化")

​ 將上述的Test.py文件導入,進行測試。學習

 1>>> from Test import *
2>>> value
3'Java'
4>>> _otherValue
5Traceback (most recent call last):
6  File "<pyshell#4>", line 1in <module>
7    _otherValue
8NameError: name '_otherValue' is not defined
9>>> method()
10我是普通方法
11>>> _otherMethod()
12Traceback (most recent call last):
13  File "<pyshell#6>", line 1in <module>
14    _otherMethod()
15NameError: name '_otherMethod' is not defined
16>>> p=PClass()
17普通類的初始化
18>>> w=_WClass()
19Traceback (most recent call last):
20  File "<pyshell#8>", line 1in <module>
21    w=_WClass()
22NameError: name '_WClass' is not defined

​ 從上面的結果能夠看出,不論是屬性、方法和類,只要名稱前面加了單下劃線,都不能導出。測試

​ 若是對程序進行修改,將在開頭加入_ all _,結果會是如何?ui

 1# Test.py 文件
2
3#將普通屬性、單下劃線的屬性、方法、和類加入__all__列表
4__all__=["value""_otherValue","_otherMethod","_WClass"]
5
6#普通屬性
7value="Java"
8
9#單下劃線屬性
10_otherValue="Python"
11
12#普通方法
13def  method():
14    print("我是普通方法")
15
16#單下劃線方法
17def _otherMethod():
18    print("我是單下劃線方法")
19
20#普通類
21class PClass(object):
22
23    def __init__(self):
24        print("普通類的初始化")
25
26#單下劃線類
27class _WClass(object):
28
29    def __init__(self):
30        print("單下劃線類的初始化")

​ 將上述修改過的Test.py文件導入,進行測試。spa

 1>>> from Test import *
2>>> value
3'Java'
4>>> _otherValue
5'Python'
6>>> method()
7Traceback (most recent call last):
8  File "<pyshell#4>", line 1in <module>
9    method()
10NameError: name 'method' is not defined
11>>> _otherMethod()
12我是單下劃線方法
13>>> p=PClass()
14Traceback (most recent call last):
15  File "<pyshell#6>", line 1in <module>
16    p=PClass()
17NameError: name 'PClass' is not defined
18>>> w= _WClass()
19單下劃線類的初始化

_ all _是一個字符串列表,不論是普通的仍是單下劃線的屬性、方法和類,都將導出來,使用其餘不在這個字符列表上的屬性、方法和類,都會報未定義的錯誤。

​ 不論是屬性、方法和類,只要名稱前面加了單下劃線,都不能導入。除非是模塊或包中的「_ all_」列表顯式地包含了它們。

名稱前的雙下劃線(如:__name)

​ 咱們先看看下面的程序:

 1class Method(object):
2    # 構造器方法
3    def __init__(self, name):
4        # 雙下劃線屬性
5        self.__name = name
6    # 普通方法
7    def sayhello(self):
8        print("Method say hello!")
9    # 雙下劃線方法
10    def __sayhi(self):
11        print("Method say hi!")
12
13# 初始化Method
14m = Method("Python")
15# 調用sayhello方法
16m.sayhello()
17# 調用sayhi方法
18m.__sayhi()
19# 輸出屬性__name
20print(m.__name)

​ 上面的程序定義了一個類,這個類有三個方法,一個構造器方法,一個普通方法,一個雙下劃線方法,以及包括一個雙下劃線的屬性。上面的結果輸出的是什麼?不少讀者可能認爲輸出的結果以下:

1Method say hello!
2Method say hi!
3Python

​ 那麼恭喜你,上面的輸出結果是錯誤的,實際輸出的結果爲:

1Method say hello!
2Traceback (most recent call last):
3  File "<encoding error>", line 18in <module>
4AttributeError: 'Method' object has no attribute '__sayhi'

​ 實際上,當對象調用__sayhi()方法時,將會報Method類沒有這個方法屬性的錯誤。那如何去調用以雙下劃線開頭的方法和屬性?Python這樣設計的目的是什麼?

​ 首先回答第一個問題,讀者看完下面的程序就知道怎麼調用了。

 1class Method(object):
2
3    def __init__(self, name):
4        self.__name = name
5
6    def sayhello(self):
7        print("Method say hello!")
8
9    def __sayhi(self):
10        print("Method say hi!")
11
12
13# 初始化Method
14m = Method("Python")
15# 調用sayhello方法
16m.sayhello()
17# 調用sayhi方法
18#m.__sayhi()
19m._Method__sayhi()
20# 輸出屬性__name
21#print(m.__name)
22print(m._Method__name)

​ 輸出結果以下:

1Method say hello!
2Method say hi!
3Python

​ 咱們從上面的程序中能夠很清楚的看到,若是要調用以雙下劃線開頭的方法和屬性,只要以「類名_方法(屬性)」的形式就能夠實現方法或者屬性的訪問了。類前面是單下劃線,類名後面是雙下劃線,而後再加上方法或者屬性。可是並不建議調用,由於這是Python內部進行調用的形式。

​ 回答完第一個問題,咱們看看第二個問題,Python這樣設計的目的是什麼?

​ 有不少人認爲,Python以雙下劃線開頭的方法和屬性表示私有的方法和屬性,實際上這樣的理解不太準確,也不能說徹底錯誤的。可是這並非Python設計的目的和初衷,咱們先看看下面一段程序和程序運行結果:

 1class AMethod(object):
2
3    def __method(self):
4        print("__method in class Amethod!")
5
6    def method(self):
7        self.__method()
8        print("anthod method in class AMethod!")
9
10class BMethod(AMethod):
11
12    def __method(self):
13        print("__method in class Bmethod!")
14
15
16if __name__=="__main__":
17
18    print("調用AMethod的method方法")
19    a = AMethod()
20    a.method()
21
22    print("調用BMethod的method方法")
23    b = BMethod()
24    b.method()

​ 上面的程序定義了兩個類,一個是AMethod類,另一個是繼承了AMethod類的BMethod類。在AMethod類中,定義了兩個方法,一個是以雙下劃線開頭的__method方法,另一個是普通方法。在BMethod類中,重寫了AMethod類中的__method方法。

​ 程序運行結果:

1調用AMethod的method方法
2__method in class Amethod!
3anthod method in class AMethod!
4調用BMethodmethod方法
5__method in class Amethod!
6anthod method in class AMethod!
7

​ 運行結果並非咱們想要的結果,b.method()並無調用BMethod類的__method方法,而這個設計的實際目的是爲了不父類的方法被子類輕易的覆蓋。

名稱先後的雙下劃線(如:_ init _

​ 在Python類中,咱們能夠經常看到相似於「_ init _ 」的方法,這表示在Python內部調用的方法,通常不建議在程序中調用。好比,當調用len()方法時,實際上調用了 Python中內部的 _ len _ 方法,雖然不建議調用這種以雙下劃線開頭以及結尾的方法,可是能夠對這些方法進行重寫。好比下面的例子:

 1class Number(object):
2
3    def __init__(self, number):
4        self.number = number
5
6    def __add__(self, number):
7        # 重寫方法,返回兩個數的差值
8        return self.number - number
9
10    def __sub__(self, number):
11        # 重寫方法,返回兩個數的和
12        return self.number + number
13
14    def __str__(self):
15        # 重寫方法,返回字符串
16        return str(self.number)
17
18
19num = Number(100)
20print(num) # 100 調用了__str__方法
21print(num+50# 50 + 調用了__add__方法
22print(num-20# 120 -調用了__sub__方法

​ 相信看了上面全部對Python中下劃線做用的講解,徹底可以理解上述四種下劃線所表示的意義。最後將對上面的,進行總結。

總結

  • 單下劃線(_): 在交互解釋器中,表示上一條語句執行輸出的結果。另外,單下劃線還能夠做爲特殊的臨時變量,表示在後面將不會在用到這個變量。

  • 名稱前的單下劃線:只能在內部使用,是API中非公開的部分,不能被 import * 和 from import *導入程序中,除非在all列表中包含了以單下劃線開頭的屬性、方法以及類。

  • 名稱前的雙下劃線:以雙下劃線開頭的屬性、方法表示避免父類的屬性和方法被子類輕易的覆蓋,通常不建議這樣定義屬性和方法,除非你本身將要作什麼。

  • 名稱先後的雙下劃線:這類方法是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寶典今日頭條號地址:http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826

........................................................................................................................

● 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

● 文章內容來源於小麥苗的學習筆記,部分整理自網絡,如有侵權或不當之處還請諒解

● 版權全部,歡迎分享本文,轉載請保留出處

........................................................................................................................

小麥苗的微店https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

小麥苗出版的數據庫類叢書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,學習最實用的數據庫技術。

........................................................................................................................

歡迎與我聯繫
相關文章
相關標籤/搜索