tutorial lenguaje español descargar python

lenguaje - python wikipedia



¿Por qué es "if not someobj:" better than "if someobj== None:" en Python? (9)

He visto varios ejemplos de código como este:

if not someobj: #do something

Pero me pregunto por qué no hacer:

if someobj == None: #do something

Hay alguna diferencia? ¿Uno tiene una ventaja sobre el otro?


En la primera prueba, Python intenta convertir el objeto a un valor bool si aún no es uno. Aproximadamente, estamos preguntando el objeto: ¿tienes sentido o no? Esto se hace usando el siguiente algoritmo:

  1. Si el objeto tiene un método especial __nonzero__ (como lo hacen los complementos numéricos, int y float ), llama a este método. Debe devolver un valor bool que luego se usa directamente, o un valor int que se considera False si es igual a cero.

  2. De lo contrario, si el objeto tiene un método especial __len__ (como lo hacen los contenedores integrados, list , dict , set , tuple , ...), llama a este método, considerando un contenedor False si está vacío (la longitud es cero).

  3. De lo contrario, el objeto se considera True menos que sea None en cuyo caso, se considera False .

En la segunda prueba, el objeto se compara por igualdad con None . Aquí, estamos preguntando al objeto, "¿Eres igual a este otro valor?" Esto se hace usando el siguiente algoritmo:

  1. Si el objeto tiene un método __eq__ , se llama y el valor de retorno se convierte a un valor bool y se usa para determinar el resultado del if .

  2. De lo contrario, si el objeto tiene un método __cmp__ , se llama. Esta función debe devolver un int indique el orden de los dos objetos ( -1 si self < other , 0 si self == other , +1 si self > other ).

  3. De lo contrario, el objeto se compara con la identidad (es decir, son referencias al mismo objeto, como puede probar el operador is ).

Hay otra prueba posible usando el operador is . Le estaríamos preguntando al objeto, "¿Eres este objeto en particular?"

En general, recomendaría utilizar la primera prueba con valores no numéricos, usar la prueba de igualdad cuando desee comparar objetos de la misma naturaleza (dos cadenas, dos números, ...) y verificar la identidad solo cuando utilizando valores centinela ( None significa que no se ha inicializado para un campo miembro por ejemplo, o cuando se usan los getattr o __getitem__ ).

Para resumir, tenemos:

>>> class A(object): ... def __repr__(self): ... return ''A()'' ... def __nonzero__(self): ... return False >>> class B(object): ... def __repr__(self): ... return ''B()'' ... def __len__(self): ... return 0 >>> class C(object): ... def __repr__(self): ... return ''C()'' ... def __cmp__(self, other): ... return 0 >>> class D(object): ... def __repr__(self): ... return ''D()'' ... def __eq__(self, other): ... return True >>> for obj in ['''', (), [], {}, 0, 0., A(), B(), C(), D(), None]: ... print ''%4s: bool(obj) -> %5s, obj == None -> %5s, obj is None -> %5s'' % / ... (repr(obj), bool(obj), obj == None, obj is None) '''': bool(obj) -> False, obj == None -> False, obj is None -> False (): bool(obj) -> False, obj == None -> False, obj is None -> False []: bool(obj) -> False, obj == None -> False, obj is None -> False {}: bool(obj) -> False, obj == None -> False, obj is None -> False 0: bool(obj) -> False, obj == None -> False, obj is None -> False 0.0: bool(obj) -> False, obj == None -> False, obj is None -> False A(): bool(obj) -> False, obj == None -> False, obj is None -> False B(): bool(obj) -> False, obj == None -> False, obj is None -> False C(): bool(obj) -> True, obj == None -> True, obj is None -> False D(): bool(obj) -> True, obj == None -> True, obj is None -> False None: bool(obj) -> False, obj == None -> True, obj is None -> True


En realidad, ambas son prácticas deficientes. Hubo un tiempo en que se consideraba aceptable tratar casualmente Ninguno y Falso como similares. Sin embargo, desde Python 2.2 esta no es la mejor política.

Primero, cuando haces un tipo de prueba if x o if not x , Python tiene que convertir implícitamente x a boolean. Las reglas para la función bool describen una gran cantidad de cosas que son falsas; todo lo demás es Verdadero Si el valor de x no era propiamente booleano para empezar, esta conversión implícita no es realmente la forma más clara de decir cosas.

Antes de Python 2.2, no había función bool, por lo que era aún menos claro.

En segundo lugar, no debería realmente probar con == None . Deberías usar is None y is not None .

Ver PEP 8, Guía de estilo para el código de Python .

- Comparisons to singletons like None should always be done with ''is'' or ''is not'', never the equality operators. Also, beware of writing "if x" when you really mean "if x is not None" -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!

¿Cuántos singleton hay? Cinco: None , True , False , no NotImplemented y Ellipsis . Dado que es poco probable que use NotImplemented o Ellipsis , y nunca diría if x is True (porque simplemente if x es mucho más claro), solo probará None .


Estas dos comparaciones sirven para diferentes propósitos. El primero verifica el valor booleano de algo, el segundo comprueba la identidad con el valor Ninguno.


La respuesta es, depende".

Utilizo el primer ejemplo si considero que 0, "", [] y False (lista no exhaustiva) son equivalentes a Ninguno en este contexto.


Para uno, el primer ejemplo es más corto y se ve mejor. Según las otras publicaciones, lo que elijas también depende de lo que realmente quieras hacer con la comparación.


Personalmente, elegí un enfoque coherente en todos los idiomas: lo hago if (var) (o equivalente) solo si var se declara como booleano (o se define como tal, en C no tenemos un tipo específico). Incluso prefijo estas variables con una b (por lo que sería bVar realidad) para asegurarme de que no bVar accidentalmente otro tipo aquí.
Realmente no me gusta la conversión implícita a boolean, incluso menos cuando hay numerosas reglas complejas.

Por supuesto, las personas estarán en desacuerdo. Algunos van más allá, veo if (bVar == true) en el código Java en mi trabajo (¡demasiado redundante para mi gusto!), Otros adoran demasiada sintaxis compacta, yendo while (line = getNextLine()) (demasiado ambiguo para mí )


Porque None no es lo único que se considera falso.

if not False: print "False is false." if not 0: print "0 is false." if not []: print "An empty list is false." if not (): print "An empty tuple is false." if not {}: print "An empty dict is false." if not "": print "An empty string is false."

False , 0 , () , [] , {} y "" son todos diferentes de None , por lo que los dos fragmentos de código no son equivalentes.

Por otra parte, considere lo siguiente:

>>> False == 0 True >>> False == () False

if object: no es una verificación de igualdad. 0 , () , [] , None , {} , etc. son todos diferentes entre sí, pero todos evalúan a Falso.

Esta es la "magia" detrás de las expresiones de cortocircuito como:

foo = bar and spam or eggs

que es la abreviatura de:

if bar: foo = spam else: foo = eggs

aunque realmente deberías escribir:

foo = spam if bar else egg


Si preguntas

if not spam: print "Sorry. No SPAM."

se llama al método de spam __nonzero__ . Del manual de Python:

__nonzero__ ( self ) Invocado para implementar la prueba del valor de verdad, y la operación incorporada bool (); debería devolver False o True, o sus enteros equivalentes 0 o 1. Cuando este método no está definido, se llama a __len __ (), si está definido (ver a continuación). Si una clase no define ni __len __ () ni __nonzero __ (), todas sus instancias se consideran verdaderas.

Si preguntas

if spam == None: print "Sorry. No SPAM here either."

se llama al método __eq__ de correo no deseado con el argumento Ninguno .

Para obtener más información sobre las posibilidades de personalización, eche un vistazo a la documentación de Python en https://docs.python.org/reference/datamodel.html#basic-customization


PEP 8: la Guía de estilo para el código de Python recomienda usar es o no es si está probando la inexistencia

- Comparisons to singletons like None should always be done with ''is'' or ''is not'', never the equality operators.

Por otro lado, si está probando más de None-ness, debe usar el operador booleano.