Entiendo que los tipos integrados de Python tienen un valor de "veracidad", y la cadena vacía se considera False, mientras que cualquier cadena no vacía se considera True.

Esto tiene sentido

Puedo verificar esto usando la función incorporada bool.

>>> bool("")
False

>>> bool("dog")
True

También puedo hacer uso de estos valores de veracidad cuando uso condicionales. Por ejemplo:

>>> if "dog":
...     print("yes")
...
yes

Esto es confuso

Sin embargo, esto no funciona con el operador ==:

>>> "dog" == True
False

>>> "dog" == False
False

¿Alguien puede explicar por qué == parece actuar de manera diferente a un condicional?

1
Dustin Michels 28 feb. 2018 a las 07:09

3 respuestas

La mejor respuesta

Consulte las prueba del valor de verdad y secciones de comparaciones de la documentación, extraídas a continuación.

En pocas palabras, la mayoría de las cosas son verdaderas por defecto, por lo que bool("dog") es cierto. El operador == compara dos objetos para la igualdad, en lugar de comparar sus veracidades, como supongo que esperaba.

4.1. Prueba de valor de verdad

Se puede probar cualquier valor de verdad de cualquier objeto, para usarlo en una condición if o while o como operando de las operaciones booleanas a continuación.

Por defecto, un objeto se considera verdadero a menos que su clase defina ya sea un método __bool__() que devuelve False o un método __len__() que devuelve cero, cuando se llama con el objeto.

Aquí están la mayoría de los objetos incorporados considerados falsos:

  • constantes definidas como falsas: None y False
  • cero de cualquier tipo numérico: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
  • secuencias y colecciones vacías: '', (), [], {}, set(), range(0)

Operaciones y funciones integradas que siempre tienen un resultado booleano devuelve 0 o Falso para falso y 1 o Verdadero para verdadero, a menos que se indique lo contrario fijado. (Excepción importante: las operaciones booleanas or y and siempre devuelve uno de sus operandos.)

4.3. Comparaciones

Los objetos de diferentes tipos, excepto diferentes tipos numéricos, nunca se comparan iguales.

...

Las instancias no idénticas de una clase normalmente se comparan como no iguales a menos que la clase defina el método __eq__().

2
MarredCheese 28 feb. 2018 a las 16:49

Cuando compara "dog" == True, también está comparando el tipo de estos objetos y no solo su valor booleano.

Ahora que True tiene un tipo bool y "dog" tiene un tipo str, no son equivalentes de acuerdo con el operador ==, independientemente de que sus valores booleanos sean igual.

Nota: Aquí se verifican tanto el tipo de objeto como los valores booleanos.

0
Ubdus Samad 28 feb. 2018 a las 04:20

Los basicos

Creo que su confusión puede venir de comparar Python con lenguajes como JavaScript donde hay un operador == y ===. Python no funciona de esta manera.

En Python, la única forma de comparar la igualdad es con == y esto compara tanto el valor como el tipo.

Por lo tanto, si compara True == "dog", la expresión es inmediatamente False porque los tipos bool y str no son tipos que se puedan comparar.

Aunque, tenga en cuenta que no significa que no haya tipos que sean comparables entre sí. Los ejemplos son set y frozenset:

frozenset({1,2,3}) == {1,2,3} # True

O simplemente int y float

1 == 1.0 # True

Este es el comportamiento para la mayoría de los tipos integrados.

La parte con clase

En el caso en que defina sus propios tipos , es decir, cuando defina clases, puede escribir __eq__ al que se llama cuando compara un objeto de clase con otro valor.

Por ejemplo, podría hacer esto (que por cierto se señaló como una idea terrible en los comentarios, no debe heredar los tipos incorporados).

class WeirdString(str):
    def __eq__(self, other):
        return str(self) == str(other) or bool(self) == bool(other)

s = WeirdString("dog")
s == True # True

En el caso de que no defina __eq__, Python recurre a la comparación de si los objetos son el mismo objeto con is.

1
Olivier Melançon 28 feb. 2018 a las 04:56