None在python中是個神奇的東西,它的含義是空,但是卻不等于空字符串、空列表、空元組、也不等于False??梢赃M行驗證:
emptyList = list() # 等于[]
emptyTuple = tuple() # 等于()
emptyString = str() # 等于""
boolVar = False
print(emptyList == None) # 值的比較
print(emptyList is None) # 地址比較
print(emptyTuple == None) # 值的比較
print(emptyTuple is None) # 地址比較
print(emptyString == None) # 值的比較
print(emptyString is None) # 地址比較
print(boolVar == None) # 值的比較
print(boolVar is None) # 地址比較
上面代碼的輸出全部為False。
None是一個單例對象,也就是在程序的生命周期內只能存在一個的對象。每次程序返回None時,會把地址指向這個單例對象。
def funA():
return None
def funB():
return None
returnValA = funA()
returnValB = funB()
noneVal = None
print(type(None)) # <class 'NoneType'>
print(id(returnValA) == id(returnValB)) # True
print(id(returnValA) == id(noneVal)) # True
print(returnValA is None) # True
print(returnValA == None) # True
可以看到兩個函數的返回值都是None時,他們返回值的地址是一致的。而不管作為函數返回值還是作為變量的None,他們的地址也是一致的。這就驗證了None是一個單例對象。
Python中進行變量比較有兩種方法:==與is,二者在含義上有根本的區(qū)別
-
==表示兩個變量指向的值是否相同 -
is表示連個變量指向的地址是否相同,也就是驗證id(var1) == id(var2)
而==是由類對象的__eq__魔法方法返回值定義的,因此我們可以輕松愚弄==判定:
class someClass(object):
def __eq__(self, other):
return True # 不管和什么對象比較都返回True
classObj = someClass()
print(classObj == None) # True
print(classObj is None) # False
此時雖然實例對象classObj并不是None,但是返回給我們的仍然是True。
另外,前面已經驗證了None不等于False,因此在在進行判空操作時,要注意兩種常用方式not和is None的區(qū)別。
但是為什么會有些人認為None和False是相同的呢?因為None在進行向布爾型的顯式或者隱式類型轉換時,得到的是False。如下例所示:
if None:
print("None is converted to True")
else:
print("None is converted to False")
這里的分支語句會進入else,即打印出None is converted to False。