<p>在Python中,我会使用一个包含这三个值之一的包装器对象;我会使用<code>True</code>、<code>False</code>和<code>None</code>。由于具有三个可能值的布尔类对象的隐式truthiness值是有问题的,我们将通过<em>完全不允许这个</em>(在<code>__nonzero__()</code>,或者在Python 3,<code>__bool__()</code>中引发异常)来解决这个问题,从而要求始终显式地进行比较,使用<code>in</code>,<code>==</code>,或者<code>!=</code>。我们将把等式实现为identity,以便只匹配特定的singleton值<code>True</code>、<code>False</code>和<code>None</code>。</p>
<pre><code>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
</code></pre>
<p>用法:</p>
<pre><code>t = Tristate(True)
t == True # True
t != False # True
t in (True, False) # True
bool(t) # Exception!
if t: print "woo" # Exception!
</code></pre>
<p>使用<code>Tristate</code>对象时,必须显式指定要匹配的值,即<code>foo == True or bar != None</code>。也可以通过<code>foo in (False, None)</code>来匹配多个值(当然,<code>in</code>两个值与<code>!=</code>一个值相反)。如果您希望能够对这些对象执行其他逻辑操作,则可以将它们作为方法实现,或者可能通过重写某些运算符来实现(遗憾的是,逻辑<code>not</code>、<code>and</code>和<code>or</code>不可重写,尽管还有<a href="http://www.python.org/dev/peps/pep-0335/" rel="noreferrer">a proposal</a>要添加这些运算符)。</p>
<p>还要注意的是,在Python中不能重写<code>id()</code>,例如<code>Tristate(None) is None</code>是<code>False</code>;这两个对象实际上是不同的。因为好的Python风格是在与singleton进行比较时使用<code>is</code>,这是不幸的,但不可避免的。</p>
<p>编辑4/27/16:添加了对将一个<code>Tristate</code>对象与另一个对象进行比较的支持。</p>