深入理解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我覺得這篇文章還是寫的比較清楚,歡迎大家交流。


推薦閱讀:

TAG:Python | Python入門 | python爬蟲 |