问题描述
可能重复:
在 Python 中实现枚举"的最佳方法是什么?
我正在编写一个函数,理想情况下,我希望返回以下三种状态之一:是"、否"和不知道".
I’m writing a function that, ideally, I’d like to return one of three states: "yes", "no", and "don’t know".
是否有任何编程语言的类型具有三个且只有三个状态?类似于布尔值,但具有三种状态而不是两种状态?
Do any programming languages have a type that has three, and only three states? Like a boolean, but with three states instead of two?
在没有这种类型的语言(如 Python)中,表示这种类型的最佳类型是什么?
In languages that don’t have such a type (like Python), what’s the best type to represent this?
目前我想我会选择一个整数(0
表示否",1
表示不知道",2
表示是"),但也许有更好的方法?整数似乎有点幻数".
Currently I think I’ll go with an integer (0
for "no", 1
for "don’t know" and 2
for "yes"), but maybe there’s a better way? Integers seem a bit "magic number".
我可以返回 True
、False
或 None
,但因为 None
会评估为 False
在大多数比较上下文中,错误似乎有点成熟.
I could return True
, False
or None
, but as None
would evaluate to False
in most comparison contexts it seems a bit ripe for errors.
推荐答案
在 Python 中,我会使用包含这三个值之一的包装器对象来做到这一点;我会使用 True
、False
和 None
.由于具有三个可能值的类布尔对象的隐含真实性值是有问题的,我们将通过完全禁止来解决这个问题(在__nonzero__()
中引发异常,或在 Python 3 中,__bool__()
),因此要求始终使用 in
、==
或 显式进行比较!=
.我们将实现相等作为标识,以便仅匹配特定的单例值 True
、False
和 None
.
In Python I'd do that with a wrapper object that holds one of those three values; I'd use True
, False
, and None
. Since the implicit truthiness value of a Boolean-like object with three possible values is problematic, we'll solve that by disallowing that entirely (raising an exception in __nonzero__()
, or in Python 3, __bool__()
), thus requiring that comparisons always be done explicitly, using in
, ==
, or !=
. We'll implement equality as identity so that only the specific singleton values True
, False
, and None
are matched.
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 或 bar != None
.您也可以执行 foo in (False, None)
来匹配多个值(当然 in
两个值与 !=
相同单个值).如果您希望能够对这些对象执行其他逻辑操作,您可以将它们实现为方法,或者可能通过覆盖某些运算符(但遗憾的是,逻辑 not
、and
和 or
不可覆盖,尽管有 建议添加).
When using Tristate
objects, you must explicitly specify which values to match, i.e. foo == True or bar != None
. You can also do foo in (False, None)
to match multiple values (though of course in
two values is the same as !=
with a single value). If there are other logic operations you wish to be able to perform with these objects, you could implement these as methods, or possibly by overriding certain operators (sadly, however, logical not
, and
, and or
are not overrideable, though there's a proposal to add that).
另请注意,您不能在 Python 中覆盖 id()
,例如Tristate(None) is None
is False
;这两个对象实际上是不同的.由于好的 Python 风格是在与单例比较时使用 is
,这是不幸的,但也是不可避免的.
Also note that you can't override id()
in Python, so e.g. Tristate(None) is None
is False
; the two objects are in fact different. Since good Python style is to use is
when comparing against singletons, this is unfortunate, but unavoidable.
编辑 4/27/16:添加了将一个 Tristate
对象与另一个对象进行比较的支持.
Edit 4/27/16: Added support for comparing one Tristate
object to another.
这篇关于布尔值有两个可能的值.是否存在具有三个可能值的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!