欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python中單下劃線與雙下劃線的區(qū)別及說(shuō)明

 更新時(shí)間:2023年09月19日 10:17:05   作者:格子衫雙肩包  
這篇文章主要介紹了python中單下劃線與雙下劃線的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Python用下劃線作為前綴和后綴指定特殊變量和定義方法,主要有如下四種形式:

  • 單下劃線(_)
  • 名稱(chēng)前的單下劃線(如:_name)
  • 名稱(chēng)前的雙下劃線(如:__name)
  • 名稱(chēng)前后的雙下劃線(如:__init__)

單下劃線(_)

只有單劃線的情況,主要有兩種使用場(chǎng)景:

1、在交互式解釋器中,單下劃線“_”代表的是上一條執(zhí)行語(yǔ)句的結(jié)果。

如果單下劃線前面沒(méi)有語(yǔ)句執(zhí)行,交互式解釋器將會(huì)報(bào)單下劃線沒(méi)有定義的錯(cuò)誤。

也可以對(duì)單下劃線進(jìn)行賦值操作,這時(shí)單下劃線代表賦值的結(jié)果。

但是一般不建議對(duì)單下劃線進(jìn)行賦值操作,因?yàn)閱蜗聞澗€內(nèi)建標(biāo)識(shí)符。

>>> _
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    _
NameError: name '_' is not defined
>>> "python"
'python'
>>> _
'python'
>>> _="Java"
>>> _
'Java'
>>> 

2、單下劃線“_”還可以作為特殊的臨時(shí)變量。

如果一個(gè)變量在后面不會(huì)再用到,并且不想給這個(gè)變量定義名稱(chēng),這時(shí)就可以用單下劃線作為臨時(shí)性的變量。

比如對(duì)for循環(huán)語(yǔ)句遍歷的結(jié)果元素并不感興趣,此時(shí)就可以用單下劃線表示。

# _ 這個(gè)變量在后面不會(huì)用到
for _ in range(5):
    print("Python")

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

當(dāng)在屬性和方法前面加上單下劃線“_”,用于指定屬性和方法是“私有”的。

但是Python不像Java一樣具有私有屬性、方法、類(lèi),在屬性和方法之前加單下劃線,只是代表該屬性、方法、類(lèi)只能在內(nèi)部使用,是API中非公開(kāi)的部分。

如果用fromimport * 和 fromimport * 時(shí),這些屬性、方法、類(lèi)將不被導(dǎo)入。

# Test.py 文件
#普通屬性
value="Java"
#單下劃線屬性
_otherValue="Python"
#普通方法
def  method():
    print("我是普通方法")
#單下劃線方法
def _otherMethod():
    print("我是單下劃線方法")
#普通類(lèi)
class PClass(object):
    def __init__(self):
        print("普通類(lèi)的初始化")
#單下劃線類(lèi)
class _WClass(object):
    def __init__(self):
        print("單下劃線類(lèi)的初始化")

將上述的Test.py文件導(dǎo)入,進(jìn)行測(cè)試。

>>> 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()
普通類(lèi)的初始化
>>> w=_WClass()
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    w=_WClass()
NameError: name '_WClass' is not defined
 

從上面的結(jié)果可以看出,不管是屬性、方法和類(lèi),只要名稱(chēng)前面加了單下劃線,都不能導(dǎo)出。

如果對(duì)程序進(jìn)行修改,將在開(kāi)頭加入__all__,結(jié)果會(huì)是如何?

# Test.py 文件
#將普通屬性、單下劃線的屬性、方法、和類(lèi)加入__all__列表
__all__=["value","_otherValue","_otherMethod","_WClass"]
#普通屬性
value="Java"
#單下劃線屬性
_otherValue="Python"
#普通方法
def  method():
    print("我是普通方法")
#單下劃線方法
def _otherMethod():
    print("我是單下劃線方法")
#普通類(lèi)
class PClass(object):
    def __init__(self):
        print("普通類(lèi)的初始化")
#單下劃線類(lèi)
class _WClass(object):
    def __init__(self):
        print("單下劃線類(lèi)的初始化")

將上述修改過(guò)的Test.py文件導(dǎo)入,進(jìn)行測(cè)試。

>>> 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()
單下劃線類(lèi)的初始化

__all__是一個(gè)字符串列表,不管是普通的還是單下劃線的屬性、方法和類(lèi),都將導(dǎo)出來(lái),使用其他不在這個(gè)字符列表上的屬性、方法和類(lèi),都會(huì)報(bào)未定義的錯(cuò)誤。

不管是屬性、方法和類(lèi),只要名稱(chēng)前面加了單下劃線,都不能導(dǎo)入。

除非是模塊或包中的“__all__”列表顯式地包含了它們。

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

我們先看看下面的程序:

class Method(object):
    # 構(gòu)造器方法
    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")
# 調(diào)用sayhello方法
m.sayhello()
# 調(diào)用sayhi方法
m.__sayhi()
# 輸出屬性__name
print(m.__name)

上面的程序定義了一個(gè)類(lèi),這個(gè)類(lèi)有三個(gè)方法,一個(gè)構(gòu)造器方法,一個(gè)普通方法,一個(gè)雙下劃線方法,以及包括一個(gè)雙下劃線的屬性。

上面的結(jié)果輸出的是什么?

很多讀者可能認(rèn)為輸出的結(jié)果如下:

Method say hello!
Method say hi!
Python

那么恭喜你,上面的輸出結(jié)果是錯(cuò)誤的,實(shí)際輸出的結(jié)果為:

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

實(shí)際上,當(dāng)對(duì)象調(diào)用__sayhi()方法時(shí),將會(huì)報(bào)Method類(lèi)沒(méi)有這個(gè)方法屬性的錯(cuò)誤。

那如何去調(diào)用以雙下劃線開(kāi)頭的方法和屬性?

Python這樣設(shè)計(jì)的目的是什么?

首先回答第一個(gè)問(wèn)題,讀者看完下面的程序就知道怎么調(diào)用了。

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")
# 調(diào)用sayhello方法
m.sayhello()
# 調(diào)用sayhi方法
#m.__sayhi()
m._Method__sayhi()
# 輸出屬性__name
#print(m.__name)
print(m._Method__name)

輸出結(jié)果如下:

Method say hello!
Method say hi!
Python

我們從上面的程序中可以很清楚的看到,如果要調(diào)用以雙下劃線開(kāi)頭的方法和屬性,只要以“類(lèi)名_方法(屬性)”的形式就可以實(shí)現(xiàn)方法或者屬性的訪問(wèn)了。類(lèi)前面是單下劃線,類(lèi)名后面是雙下劃線,然后再加上方法或者屬性。但是并不建議調(diào)用,因?yàn)檫@是Python內(nèi)部進(jìn)行調(diào)用的形式。

回答完第一個(gè)問(wèn)題,我們看看第二個(gè)問(wèn)題,Python這樣設(shè)計(jì)的目的是什么?

有很多人認(rèn)為,Python以雙下劃線開(kāi)頭的方法和屬性表示私有的方法和屬性,實(shí)際上這樣的理解不太準(zhǔn)確,也不能說(shuō)完全錯(cuò)誤的。

但是這并不是Python設(shè)計(jì)的目的和初衷,我們先看看下面一段程序和程序運(yùn)行結(jié)果:

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("調(diào)用AMethod的method方法")
    a = AMethod()
    a.method()
    print("調(diào)用BMethod的method方法")
    b = BMethod()
    b.method()

上面的程序定義了兩個(gè)類(lèi),一個(gè)是AMethod類(lèi),另外一個(gè)是繼承了AMethod類(lèi)的BMethod類(lèi)。

在AMethod類(lèi)中,定義了兩個(gè)方法,一個(gè)是以雙下劃線開(kāi)頭的__method方法,另外一個(gè)是普通方法。

在BMethod類(lèi)中,重寫(xiě)了AMethod類(lèi)中的__method方法。

程序運(yùn)行結(jié)果:

調(diào)用AMethod的method方法
__method in class Amethod!
anthod method in class AMethod!
調(diào)用BMethod的method方法
__method in class Amethod!
anthod method in class AMethod!

運(yùn)行結(jié)果并不是我們想要的結(jié)果,b.method()并沒(méi)有調(diào)用BMethod類(lèi)的__method方法,而這個(gè)設(shè)計(jì)的實(shí)際目的是為了避免父類(lèi)的方法被子類(lèi)輕易的覆蓋。

名稱(chēng)前后的雙下劃線(如:__ init __)

在Python類(lèi)中,我們可以常??吹筋?lèi)似于“__ init ___”的方法,這表示在Python內(nèi)部調(diào)用的方法,一般不建議在程序中調(diào)用。

比如,當(dāng)調(diào)用len()方法時(shí),實(shí)際上調(diào)用了 Python中內(nèi)部的 ___len ___方法,雖然不建議調(diào)用這種以雙下劃線開(kāi)頭以及結(jié)尾的方法,但是可以對(duì)這些方法進(jìn)行重寫(xiě)。

比如下面的例子:

 
class Number(object):
    def __init__(self, number):
        self.number = number
    def __add__(self, number):
        # 重寫(xiě)方法,返回兩個(gè)數(shù)的差值
        return self.number - number
    def __sub__(self, number):
        # 重寫(xiě)方法,返回兩個(gè)數(shù)的和
        return self.number + number
    def __str__(self):
        # 重寫(xiě)方法,返回字符串
        return str(self.number)
num = Number(100)
print(num) # 100 調(diào)用了__str__方法
print(num+50) # 50 + 調(diào)用了__add__方法
print(num-20) # 120 -調(diào)用了__sub__方法
 

相信看了上面所有對(duì)Python中下劃線作用的講解,完全能夠理解上述四種下劃線所表示的意義。最后將對(duì)上面的,進(jìn)行總結(jié)。

總結(jié)

單下劃線(_): 在交互解釋器中,表示上一條語(yǔ)句執(zhí)行輸出的結(jié)果。另外,單下劃線還可以作為特殊的臨時(shí)變量,表示在后面將不會(huì)在用到這個(gè)變量。

名稱(chēng)前的單下劃線:只能在內(nèi)部使用,是API中非公開(kāi)的部分,不能被import * 和 fromimport *導(dǎo)入程序中,除非在all列表中包含了以單下劃線開(kāi)頭的屬性、方法以及類(lèi)。

名稱(chēng)前的雙下劃線:以雙下劃線開(kāi)頭的屬性、方法表示避免父類(lèi)的屬性和方法被子類(lèi)輕易的覆蓋,一般不建議這樣定義屬性和方法,除非你自己將要做什么。

名稱(chēng)前后的雙下劃線:這類(lèi)方法是Python內(nèi)部定義的方法,你可以重寫(xiě)這些方法,這樣Python就可以調(diào)用這個(gè)重寫(xiě)的方法以及利用操作符。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論