En Python, ¿cómo debo probar si una variable es Ninguna, Verdadera o Falsa?

9 minutos de lectura

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

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

Mi pregunta es, si se supone que no debo probar contra True o 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 quitar el == True parte o debo agregar un tipo de datos tri-bool. no quiero el simulate para lanzar una excepción, ya que todo lo que quiero que haga el programa externo con un error es registrarlo y continuar.

  • Estás haciendo la pregunta equivocada; debería pedir ayuda para definir su resultado… cuál es la diferencia que percibe entre “falla” y “error de flujo de análisis”, qué significan, cuáles son las consecuencias, qué acción es probable que la persona que llama quiera tomar en cada caso (aprobado, suspenso, error de análisis)?

    – John Maquin

    7 de enero de 2010 a las 14:01

  • Estoy simulando un sistema de energía eléctrica, si las personas pierden energía en sus casas, es una falla. Si no puedo leer el archivo de simulación, entonces es un error de un tipo completamente diferente.

    – James Brooks

    7 de enero de 2010 a las 14:06

  • Dentro de simulate funcion capto todas las excepciones; No quiero que nada de lo que suceda dentro del simulador detenga la ejecución del resto del programa (y el procesamiento del siguiente elemento). Pero las respuestas me están haciendo cambiar de opinión.

    – James Brooks

    7 de enero de 2010 a las 15:06

  • @James Brooks: Correcto. De eso se trata el procesamiento try/except. Si tu simulate tiene cosas que puede atrapar y volver a intentar, eso es bueno. Pero si “falla”, no debe volver None. Simplemente debería generar una excepción al script que lo llamó. De todas formas, simulate está hecho. regresando None no es tan útil como generar una excepción adecuada, o permitir que una excepción se propague a través de simulate en el script de llamada para su manejo.

    – S. Lott

    7 de enero de 2010 a las 15:34

  • @James, usa except Exception: en cambio. Esto captura todos los errores “reales”, junto con Warning y StopIteration. Eso permite KeyboardInterrupt y SystemExit aunque. Si realmente desea detectarlos, probablemente sea mejor usar otra estructura externa try/except o alguna otra estructura que documente claramente su intención, ya que esos no son “errores”. (Pero dije “casi nunca”… tal vez en tu caso realmente quieras tomar todo, e incluso evitar Ctrl-C o sys.exit() de salir, etc.)

    –Peter Hansen

    22 de enero de 2010 a las 17:41

avatar de usuario
Fantasma silencioso

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 simulate función para incluir más códigos de retorno, mantener este código puede convertirse en un problema.

los simulate también podrí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.

  • Este último es una especie de prueba explícita contra Verdadero o Falso, ¿no es así?

    –Peter Eisentraut

    7 de enero de 2010 a las 13:42

  • por supuesto, pero sabiendo que estos son solo posibles valores de retorno, no creo que sea un problema.

    – Fantasma silencioso

    7 de enero de 2010 a las 13:43

  • y parece ser un poco más rápido también

    – Fantasma silencioso

    7 de enero de 2010 a las 13:45

  • a = ‘foo’ si a: imprime ‘es cierto’ a no es realmente VERDADERO, simplemente no es ninguno

    – Wesm

    03/04/2015 a las 21:06

  • y simplemente no es falso

    – 00schneider

    13 de agosto de 2020 a las 11:16

avatar de usuario
PabloMcG

¡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.

  • Acordado. Mucho más pitónico que la solución evidentemente más popular anterior (que huele demasiado a código C).

    – Brandón

    7 de enero de 2010 a las 13:53

  • @Brandon No estoy de acuerdo. Este código es más largo y, peor aún, menos legible que la solución anterior (o la versión mejorada a continuación): más sangrías, más declaraciones diferentes: adivina por qué este último es más popular, como dices … 😉 ¿Por qué intentar ser ¿’Pythonic’ si eso lleva a un código más incómodo…?

    – Rolf Bartstra

    6 de diciembre de 2012 a las 16:47

  • Ahora imprima el rastreo en lugar de “flujo de análisis de error” y obtuvo mi voto.

    – CivFan

    14/10/2015 a las 19:34

  • Ok, tienes mi voto de todos modos, pero quise imprimir algo como traceback.format_exc() . Ver esta respuesta SO.

    – CivFan

    22/10/2015 a las 19:32

  • Mucha gente vendrá a esta página buscando la respuesta a la pregunta del título. Para la mayoría de nosotros “¡No temas la excepción!” no tiene nada que ver con nuestra situación. Solo necesitamos probar Verdadero, Falso y Ninguno. Si bien su alternativa sugerida es válida para algunos casos, creo que es mejor incluir también una respuesta a la pregunta tal como se formuló.

    – inmensamente superior

    29 de enero de 2016 a las 22:09

Nunca, nunca, nunca digas

if something == True:

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

Peor aún, nunca, nunca, nunca digas

if something == False:

Tú tienes not. Sientase libre de usarlo.

Finalmente, haciendo a == None es ineficiente Hacer a is None. None es un objeto singleton especial, solo puede haber uno. Solo verifica si tienes ese objeto.

  • Prueba de igualdad con True no es redundante (aunque estoy de acuerdo en que no es sensato). Podría estar llamando a un __eq__ u otro método especial, que podría hacer prácticamente cualquier cosa.

    – Scott Griffiths

    8 de enero de 2010 a las 11:43

  • @Scott Griffiths: Buen punto. Ese es un escenario verdaderamente y profundamente horrible. Si ese es realmente el caso, el programa viola nuestras expectativas fundamentales de una manera que lo convierte en algo que simplemente debe eliminarse y reescribirse desde cero sin tanta magia negra.

    – S. Lott

    8 de enero de 2010 a las 12:47

  • ‘Nunca nunca nunca’ …? Aunque hay casos que if something == True da un resultado diferente al if somethingpor ejemplo, para no booleano something. 2==True da falso mientras que 2 se evalúa como verdadero; None==False es falso pero not None ¡es verdad!

    – Rolf Bartstra

    6 de diciembre de 2012 a las 16:26

  • -1 Esta respuesta es engañosa y completamente incorrecta, ya que lo que dice @Rolf Bartstra es cierto. Aunque en este caso, lo que dices pueden se aplicado.

    – Hola Adios

    22 de enero de 2014 a las 19:18

  • -1. Dado que cualquier valor distinto de cero, no vacío o de longitud distinta de cero para something devoluciones True en bool(something). En ese caso, si SÓLO desea comprobar si something tiene un valor de True es decir bool. entonces tienes que hacer if something == True OMI.

    – Samarth Shah

    23 de agosto de 2015 a las 18:54


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.

avatar de usuario
Trastylon

Quisiera subrayar que, incluso si hay situaciones en las que if expr : no es suficiente porque uno quiere asegurarse expr es True y no solo diferente de 0/None/lo que sea, is es preferible de == por la misma razón que mencionó S. Lott 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)

  • No puede ejecutar un punto de referencia una vez y decir que uno es más eficiente que el otro (aunque podría serlo). Ejecútelo muchas veces (10.000) para ver cómo se comporta en promedio.\

    – usuario1767754

    1 de junio de 2018 a las 7:03

avatar de usuario
kiannakakis

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]

  • No puede ejecutar un punto de referencia una vez y decir que uno es más eficiente que el otro (aunque podría serlo). Ejecútelo muchas veces (10.000) para ver cómo se comporta en promedio.\

    – usuario1767754

    1 de junio de 2018 a las 7:03

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad