el paralela a la Ninguno problema existe con false = 0, true = 1, desconocido = 2 (desconocido es tampoco es verdad en realidad, pero evaluará a True si no tiene cuidado).
Creo que me costó trabajo conseguir algo que se aproxime lo que quieres. Al menos obtendrá algo que se evaluará de forma trinaria en if/else y otras instancias de evaluación booleanas.
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)
Uso:
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'
Se podría hacer Sí, No y Desconocida pseudo-únicos que permitirán refinar eval un poco. Todavía podría hacer simples comprobaciones cuando sepa que su valor será sí o no, pero si intentó hacer un bool recto() (es decir, si x) en Desconocido, obtendría un TypeError. Sin embargo, esto haría su código más explícito, ya que cada vez que verificara un valor del tipo trinario, tendría que definir en su código cómo deseaba que se tratara desconocido en el contexto de ese condicional, por lo que sería un plus .
Edit: Pensé en una alternativa que requeriría un manejo menos especial pero menos flexible. Alterar por encima de esta manera:
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))
Uso:
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'
Esto tiene la ventaja de permitir distinto de cero para trabajar como llamadas de especificaciones en el desconocido, pero tiene la desventaja de tener la función eval para el conjunto desconocido en piedra de ejemplificación y de no permitir que Unknown sea un pseudo-singleton.
Esto puede ser relevante: http://stackoverflow.com/questions/36932/whats-the-best-way-to-implement-an-enum-in-python – Owen
Similar a esta pregunta, ¿no? http://stackoverflow.com/questions/36932/whats-the-best-way-to-implement-an-enum-in-python –
@ JohannesWeiß: muy posiblemente, no tengo un fondo C, y yo ' No estoy familiarizado con el concepto de enums. Se ve bien, salud. –