本文中所有代碼均運行在Python 2.7上
在實際的工作當中,我們難免要與空值打交道,相信不少初學者都會寫出下面的代碼:
if a is None:
do something.
else:
do the other thing.
這樣寫看起來不錯,但實際上會有問題。一般來講,Python
中會把下面幾種情況當做空值來處理:
- None
- False
- 0,0.0,0L
- '',(),[],{}
其中None
的特殊之處在于,它既不是數值0
,也不是某個數據結構的空值,它本身就是一個空值對象。它的類型是NoneType
,它遵循單例模式,也就是說,在同一命名空間下的所有None
其實質上都是同一個空值對象。
>>> id(None)
1795884240
>>> None == 0
False
>>> None == ''
False
>>> a = None
>>> id(a)
1795884240
>>> a == None
True
上面的判斷顯然不符合我們的期望:只有當a
被顯示賦值為None
的情況下,a==None
才為True
。
那么,對于Python
中更為廣義的None
值判斷,我們應該怎么做呢?
>>> a = '' #這里僅以空字符串為例,其他空值同樣適用
>>> if a:
... print 'a is not empty'
... else:
... print 'a is a empty string'
'a is a empty string.'
可以看出,if a
的判斷方式得出了我們想要的結果,那么if a
的判斷方式究竟是一個怎樣的過程呢?
if a
會首先去調用a的__nonzero__()
去判斷a是否為空,并返回True/False
,若一個對象沒有定義__nonzero__()
,就去調用它的__len__()
來進行判斷(這里返回值為0代表空),若某一對象沒有定義以上兩種方法,則if a
的結果永遠為True
接下來驗證一下上面的說法:
>>>class A(object):
... def __nonzero__(self):
... print 'running on the __nonzero__'
... return True
>>>class B(object):
... def __len__(self):
... print 'running on the __len__'
... return False
>>> a, b = A(), B()
>>>if a:
... print 'Yep'
... else:
... print 'Nop'
running on the __nonzero__
Yep
>>>if b:
... print 'Yep'
... else:
... print 'Nop'
running on the __len__
Nop