Tengo una función que puede devolver una de tres cosas:

  • éxito ( True)
  • fracaso ( False)
  • error al leer/analizar flujo ( None)

Mi pregunta es, si se supone que no debo probar contra Trueo False, ¿cómo debo ver cuál es el resultado? A continuación se muestra cómo lo estoy haciendo actualmente:

result = simulate(open("myfile"))
if result == None:
    print "error parsing stream"
elif result == True: # shouldn't do this
    print "result pass"
else:
    print "result fail"

¿Es realmente tan simple como eliminar la == Trueparte o debo agregar un tipo de datos tri-bool? No quiero que la simulatefunción arroje una excepción, ya que todo lo que quiero que haga el programa externo con un error es registrarlo y continuar.

respuesta
if result is None:
    print "error parsing stream"
elif result:
    print "result pass"
else:
    print "result fail"

mantenlo simple y explícito. Por supuesto, puede predefinir un diccionario.

messages = {None: 'error', True: 'pass', False: 'fail'}
print messages[result]

Si planea modificar su simulatefunción para incluir más códigos de retorno, mantener este código puede convertirse en un problema.

También simulatepodría generar una excepción en el error de análisis, en cuyo caso lo detectaría aquí o dejaría que se propague un nivel superior y el bit de impresión se reduciría a una declaración if-else de una línea.

¡No temas la Excepción! Hacer que su programa inicie sesión y continúe es tan fácil como:

try:
    result = simulate(open("myfile"))
except SimulationException as sim_exc:
    print "error parsing stream", sim_exc
else:
    if result:
        print "result pass"
    else:
        print "result fail"

# execution continues from here, regardless of exception or not

Y ahora puede tener un tipo de notificación mucho más rica del método de simulación en cuanto a lo que salió mal exactamente, en caso de que encuentre que el error/sin error no es lo suficientemente informativo.

Nunca, nunca, nunca digas

if something == True:

Nunca. Es una locura, ya que está repitiendo de forma redundante lo que se especifica de forma redundante como la regla de condición redundante para una declaración if.

Peor aún, nunca, nunca, nunca digas

if something == False:

tienes not_ Sientase libre de usarlo.

Finalmente, hacer a == Nonees ineficiente. hacer a is None_ Nonees un objeto singleton especial, solo puede haber uno. Solo verifica si tienes ese objeto.

Hay muchas buenas respuestas. Me gustaría añadir un punto más. Un error puede entrar en su código si está trabajando con valores numéricos, y su respuesta es 0.

a = 0 
b = 10 
c = None

### Common approach that can cause a problem

if not a:
    print(f"Answer is not found. Answer is {str(a)}.") 
else:
    print(f"Answer is: {str(a)}.")

if not b:
    print(f"Answer is not found. Answer is {str(b)}.") 
else:
    print(f"Answer is: {str(b)}")

if not c:
    print(f"Answer is not found. Answer is {str(c)}.") 
else:
    print(f"Answer is: {str(c)}.")
Answer is not found. Answer is 0.   
Answer is: 10.   
Answer is not found. Answer is None.
### Safer approach 
if a is None:
    print(f"Answer is not found. Answer is {str(a)}.") 
else:
    print(f"Answer is: {str(a)}.")

if b is None:
    print(f"Answer is not found. Answer is {str(b)}.") 
else:
    print(f"Answer is: {str(b)}.")

if c is None:
    print(f"Answer is not found. Answer is {str(c)}.") 
else:
    print(f"Answer is: {str(c)}.")

Answer is: 0.
Answer is: 10.
Answer is not found. Answer is None.

Me gustaría enfatizar que, incluso si hay situaciones en las if expr :que no es suficiente porque uno quiere asegurarse de que expres Truey no solo diferente de 0/ None/lo que sea, isdebe == preferirse por la misma razón que S. Lott mencionó para evitar== None .

De hecho, es un poco más eficiente y, como cereza del pastel, más legible para los humanos.

In [1]: %timeit (1 == 1) == True
38.1 ns ± 0.116 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [2]: %timeit (1 == 1) is True
33.7 ns ± 0.141 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Creo que lanzar una excepción es una mejor idea para su situación. Una alternativa será el método de simulación para devolver una tupla. El primer elemento será el estado y el segundo el resultado:

result = simulate(open("myfile"))
if not result[0]:
  print "error parsing stream"
else:
  ret= result[1]