在Python中,我将使用包含这三个值之一的包装对象来完成此操作;我会使用True
,False
和None
。由于具有三个可能值的类布尔对象的隐式真值是有问题的,因此我们将通过完全禁止 (在__nonzero__()
或Python 3中引发异常)来解决此问题__bool__()
,因此要求始终使用in
,==
或!=
。所以只有特定的单值,我们将实现平等的身份True
,False
以及None
相匹配。
class Tristate(object):
def __init__(self, value=None):
if any(value is v for v in (True, False, None)):
self.value = value
else:
raise ValueError("Tristate value must be True, False, or None")
def __eq__(self, other):
return (self.value is other.value if isinstance(other, Tristate)
else self.value is other)
def __ne__(self, other):
return not self == other
def __nonzero__(self): # Python 3: __bool__()
raise TypeError("Tristate object may not be used as a Boolean")
def __str__(self):
return str(self.value)
def __repr__(self):
return "Tristate(%s)" % self.value
用法:
t = Tristate(True)
t == True # True
t != False # True
t in (True, False) # True
bool(t) # Exception!
if t: print "woo" # Exception!
使用Tristate
对象时,必须明确指定要匹配的值,即foo == True or bar != None
。您也foo in (False, None)
可以匹配多个值(当然,in
两个值!=
与单个值相反)。如果有其他的逻辑运算,你希望能够与这些对象进行,你可以为方法,或者可能通过重写某些运营商(实现这些可悲的是,然而,逻辑not
,and
和or
不覆写投放,但有一个建议,以添加)。
还要注意的是,你不能覆盖id()
在Python,所以如Tristate(None) is None
为False
; 这两个对象实际上是不同的。由于is
在与单例进行比较时会使用良好的Python样式,因此这是不幸的,但不可避免。