在第一个测试中,Python尝试将对象转换为
bool值(如果尚未转换为值)。粗略地, 我们在问对象:您有意义吗? 这可以通过以下算法完成:
如果对象具有
__nonzero__
特殊方法(如数字内置int
和float
),则它将调用此方法。它必须要么返回bool
其随后直接使用值,或者int
被认为是值False
如果等于零。否则,如果对象有一个
__len__
特殊的方法(如做容器内置插件,list
,dict
,set
,tuple
,…),它会调用这个方法,考虑一个容器False
,如果它是空的(长度为零)。否则,该对象被认为是
True
,除非它是None
在这种情况下,它被认为是False
。
在第二个测试中,将对象与进行相等性比较
None。在这里, 我们问对象:“您等于这个其他值吗?” 这可以通过以下算法完成:
如果对象具有
__eq__
方法,则将其调用,然后将返回值转换为一个bool
值,并用于确定的结果if
。否则,如果对象具有
__cmp__
方法,则将其调用。此函数必须返回一个int
指示两个对象的顺序的指示符(-1
ifself < other
,0
ifself == other
,+1
ifself > other
)。否则,比较对象的身份(即,它们引用了同一对象,可以由
is
操作员进行测试)。
使用
is运算符可以进行另一项测试。 我们会问对象“您是这个特定对象吗?”
通常,我建议对非数字值使用第一个测试,如果要比较具有相同性质(两个字符串,两个数字,…)的对象,并且仅在以下情况下检查身份,请使用该测试是否相等使用哨兵值(例如,
None未针对成员字段初始化,或使用
getattr或
__getitem__方法时未初始化)。
总而言之,我们有:
>>> class A(object):... def __repr__(self):... return 'A()'... def __nonzero__(self):... return False>>> class B(object):... def __repr__(self):... return 'B()'... def __len__(self):... return 0>>> class C(object):... def __repr__(self):... return 'C()'... def __cmp__(self, other):... return 0>>> class D(object):... def __repr__(self):... return 'D()'... def __eq__(self, other):... return True>>> for obj in ['', (), [], {}, 0, 0., A(), B(), C(), D(), None]:... print '%4s: bool(obj) -> %5s, obj == None -> %5s, obj is None -> %5s' % ... (repr(obj), bool(obj), obj == None, obj is None) '': bool(obj) -> False, obj == None -> False, obj is None -> False (): bool(obj) -> False, obj == None -> False, obj is None -> False []: bool(obj) -> False, obj == None -> False, obj is None -> False {}: bool(obj) -> False, obj == None -> False, obj is None -> False 0: bool(obj) -> False, obj == None -> False, obj is None -> False 0.0: bool(obj) -> False, obj == None -> False, obj is None -> False A(): bool(obj) -> False, obj == None -> False, obj is None -> False B(): bool(obj) -> False, obj == None -> False, obj is None -> False C(): bool(obj) -> True, obj == None -> True, obj is None -> False D(): bool(obj) -> True, obj == None -> True, obj is None -> FalseNone: bool(obj) -> False, obj == None -> True, obj is None -> True


