天天看點

深入了解Python中的None

Python中的None是一個經常被用到的知識點,但是很多人對于None的内涵把握的還是不夠精确,今天就和我一起好好了解下這個小知識點吧。

1.None表示空,但它不等于空字元串、空清單,也不等同于False,通過下面的代碼進行驗證。

a = ''
b = False
c = []

print(a==None)   #比較值
print(b==None)
print(c==None)

print(a is None)           

複制

False
False
False
False           

複制

2.在寫代碼的過程中,會對某些代碼進行判空操作。比如有一個變量a,那麼if not a和if a is None兩者有差別嗎?如果說沒有差別,那麼不管a為何值時,這兩個判斷語句會傳回相同的結果,但事實是這樣嗎?一起看下面這段代碼,體會一下對None的判空操作

def fun():
    return None

a =fun()
if not a:   #邏輯運算
    print('S')
else:
    print('F')

if a is None:
    print('S')
else:
    print('F')           

複制

S
S           

複制

運作代碼發現,結果是一樣的,這是由于我們調用函數時,會傳回None,那麼此時兩個判斷語句傳回的結果是一樣的,但是如果我們将a的值換成一個空清單,會出現什麼結果呢?

def fun():
    return None

a = []
if not a:   #邏輯運算
    print('S')
else:
    print('F')

if a is None:
    print('S')
else:
    print('F')           

複制

S
F           

複制

運作結果,發現會列印不一樣的值。那麼這是為什麼呢?對于not a它的意思相當于True,是以會列印出S,而a is None是比較運算,它們不屬于同一種類型,是以會出現不一樣的列印值。

那麼對于判空操作文法調用,我一般推薦這樣操作

if not a:           

複制

通過這樣一個判空操作,不管a是None還是空字元串、空清單或者布爾值,你都會得到想要的值。

3.None和False

很多時候,當我們運作if None和if False會得到相同的結果,但結果相同并不代表意義一樣。

從類型層面上,False是布爾類型,而None是class 'NoneType';從意義層面上,None表示不存在,而False表示真假。

4.對象存在并不一定是True

通過編寫一個具體執行個體來進行說明,代碼如下

class Test():
    def __len__(self):
        return 0

test = Test()

if test:   #存在
    print('S')
else:
    print('F')           

複制

F           

複制

是以說,永遠不要認為對象存在一定會進入if分支中,即使執行個體化對象不取 None它也有可能進入else分支中。

我們可以用bool來說明一下原因,代碼如下

class Test():
    def __len__(self):
        return 0

test = Test()

print(bool(None))
print(bool([]))
print(bool(test))


if test:   #存在
    print('S')
else:
    print('F')           

複制

False
False
False
F           

複制

可以直覺的看出來,test的布爾值是False,是以它最終是會進入else分支的。是以,對于自定義的對象,千萬不要認為隻要對象存在就一定列印True。

5.__len__與__bool__内置方法

那麼對象到底是True還是False取決于類下面的内置方法,具體代碼如下

class Test():
    # def __bool__(self):
    #     return False   #不能傳回整形,
    def __len__(self):
        return 0   #可以傳回布爾值,特例


print(bool(Test()))           

複制

False           

複制

首先運作len方法,注釋掉bool方法,我們會發現,如果len方法傳回0,那麼對象布爾值是False,如果傳回其他數字則是True,但是len方法下面的return隻能傳回整形和布爾值,其他的傳回值,比如字元串、浮點數,都會報錯的,有興趣的同學可以驗證一下。

然後,再加入bool方法後,對象的布爾值則由bool方法确定,代碼如下

class Test():
    def __bool__(self):
        return False   #不能傳回整形,
    def __len__(self):
        return 0   #可以傳回布爾值,特例

print(bool(Test()))           

複制

False           

複制

這裡需要強調的是,bool類型的return隻能傳回False或True,為什麼說這個呢?因為我們都知道,Python中False相當于0,True相當于1,但這裡如果我們将False改為0,那麼結果會出錯,如下

TypeError: __bool__ should return bool, returned int           

複制

是以再小的知識點,如果我們深挖下去,背後都有複雜的知識體系,關于None我覺得這篇文章還是寫的比較清楚,歡迎大家交流。