Booleans have two possible values. Are there types that have three possible values?
Possible Duplicate:
What's the best way to implement an 'enum' in Python?
我正在编写一个函数,理想情况下,我希望返回三种状态之一:"是"、"否"和"不知道"。
任何编程语言都有三种状态的类型吗?就像一个布尔值,但是有三个状态而不是两个?
在没有这种类型的语言中(比如python),最好的类型是什么?
现在我想我用一个整数(
我可以返回
在python中,我将使用一个包含这三个值之一的包装器对象;我将使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 |
用途:
1 2 3 4 5 6 | t = Tristate(True) t == True # True t != False # True t in (True, False) # True bool(t) # Exception! if t: print"woo" # Exception! |
使用
还要注意,不能在python中重写
编辑4/27/16:增加了对将一个
这被称为三值逻辑或三值逻辑。如其他答案所示,您可以实现一个类:
1 2 3 4 | class Ternary: FALSE = 0 TRUE = 1 UNKNOWN = 2 |
我自己,我可能会寻求你的解决方案(
与"无"问题平行存在,错误=0,正确=1,未知=2(未知也不是真正的,但如果不小心,将评估为真)。
我想,我想出了一个老套的方法来得到至少接近你想要的东西。它至少会为您提供一些东西,在if/else和其他布尔值eval实例中以三元形式进行评估。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class Yes(object): def __nonzero__(self): return True class No(object): def __nonzero__(self): return False class Unknown(object): def __nonzero__(self): raise ValueError('Unknown typed values do not evaluate to True/False. Try using Ternary.eval().') class Ternary(object): def __init__(self, yes, no, unknown): setattr(self, yes, Yes()) setattr(self, no, No()) setattr(self, unknown, Unknown()) @staticmethod def eval(value, unknown_eval): if isinstance(value, Unknown): return unknown_eval return bool(value) |
用途:
1 2 3 4 5 6 | t = Ternary('yes', 'no', 'unknown') # Do stuff to assign ternary value to x if Ternary.eval(x, True): print 'x is yes or unknown' if Ternary.eval(x, False): print 'x is yes only' |
你可以做是,否,和未知的伪单例,这会让你改进eval一点。当你知道你的值将是"是"或"否"时,你仍然可以做简单的if检查,但是如果你试图在未知的情况下做一个直接的bool()(即如果x),你会得到一个类型错误。这将使您的代码更加明确,因为每次检查三元类型的值时,您都必须在代码中定义如何在该条件的上下文中处理未知项,因此这将是一个加号。
编辑:我想到了一个替代方案,它需要更少的特殊处理,但灵活性较差。上周四更改:
1 2 3 4 5 6 7 8 9 10 11 | class Unknown(object): def __init__(self, eval): self._eval = eval def __nonzero__(self): return self._eval class Ternary(object): def __init__(self, yes, no, unknown, unknown_eval): setattr(self, yes, Yes()) setattr(self, no, No()) setattr(self, unknown, Unknown(unknown_eval)) |
用途:
1 2 3 4 5 6 7 | t1 = Ternary('yes', 'no', 'unknown', True) t2 = Ternary('yes', 'no', 'unknown', False) # Do stuff to assign ternary values to x1 and x2 if x1: print 'x is yes or unknown' if x2: print 'x is yes only' |
这样做的好处是允许非零按照规范在未知中的要求工作,但是它有一个缺点,那就是从实例化开始对未知集进行评估,并且不再允许未知集是一个伪单例。
它通常被称为"枚举",位于该名称的C构造之后。
您可以轻松地创建自己的类,其中的对象必须用集合中的值初始化,并且可以相应地创建适当的比较、相等和真值函数。
我的DBF模块中有一个3值逻辑类。
它将
由于无法重写
它还实现了
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | from dbf import Logical, Truth, Falsth, Unknown middle_name = raw_input("What is the middle name? ['?' if unknown]").strip() if middle_name == '?': middle_name = '' middle_exists = Unknown elif middle_name: middle_exists = Truth else: middle_exists = Falsth . . . if middle_exists is Unknown: print"The middle name is unknown." elif middle_exists: print"The middle name is %s." % middle_name else: print"This person does not have a middle name." |
我从未见过类似于布尔值的类型,它有两个以上的值。毕竟,"布尔"意味着函数在"布尔域"上运行,而"布尔域"正好有2个值。
也就是说,使用整数、枚举甚至字符串是完全可以的。在python中,您可以创建一个只包含变量yes、no和maybe的模块,并从那里导入到其他地方。
我不太喜欢Python编程,但是在不知道的情况下,你能不返回一个吗?打电话的人必须检查"是"、"否"或"无",但至少他们会知道你不知道。
http://boodeb.org/main/python/tourist/none-empty-nothing
没有这样的内置类型。也不支持将枚举作为类型。但是,可以使用常量作为:
1 2 3 4 5 6 | class Option: NO = 0 DONT_KNOW = 1 YES = 2 reply = Option.YES |