python - hoverinfo - plotly layout
¿Por qué no hay una verificación explícita de vacío(por ejemplo, `está vacío`) en Python (5)
El Zen de Python dice "Explicit es mejor que implícito". Sin embargo, la forma "pythonic" de verificar el vacío es mediante el uso de booleantes implícitos:
if not some_sequence:
some_sequence.fill_sequence()
Esto será cierto si some_sequence
es una secuencia vacía, pero también si es None
o 0
.
Comparar con un control teórico explícito de vacío:
if some_sequence is Empty:
some_sequence.fill_sequence()
Con un nombre de variable elegido de manera desfavorable, el booleante implícito para verificar el vacío se vuelve aún más confuso:
if saved:
mess_up()
Comparar con:
if saved is not Empty:
mess_up()
Vea también: " Python: ¿Cuál es la mejor manera de verificar si una lista está vacía? ". Me parece irónico que la respuesta más votada afirme que implícita es pythonic.
Entonces, ¿hay una razón más alta por la que no hay una verificación de vacío explícita, como por ejemplo is Empty
en Python?
Considere que Lisp ha estado usando () la lista vacía o su símbolo NIL durante algunos años como Falso y T o cualquier cosa que no sea NIL como Verdadero, pero en general el cálculo de la Verdad ya produjo algún resultado útil que no es necesario reproducir si es necesario. Vea también el método de partición de cadenas, donde el resultado medio funciona muy bien, mientras que el control con el que no está vacío es la verdadera convención.
En general, trato de evitar el uso de len, ya que la mayoría de las veces es muy caro en bucles cerrados. A menudo vale la pena actualizar el valor de longitud del resultado en la lógica del programa en lugar de recalcular la longitud.
Para mí preferiría que Python tenga Falso como () o [] en lugar de 0, pero así es como es. Entonces sería más natural utilizar no [] como no vacío. Pero ahora () no es [] es verdadero, así que puedes usar:
emptyset = set([])
if myset == emptyset:
Si desea ser explícito del caso de conjunto vacío (no se establece myset ([]))
Yo mismo me gusta bastante el si no como mi comentarista.
Ahora pensé que tal vez esto es lo más cercano a explícito not_empty:
if any(x in myset for x in myset): print "set is not empty"
y así está vacío sería:
if not any(x in myset for x in myset): print "set is empty"
El polimorfismo en if foo:
y if not foo:
no es una violación de "implícito vs explícito": delega explícitamente al objeto que se está verificando la tarea de saber si es verdadero o falso. Lo que eso significa (y la mejor manera de comprobarlo) obviamente depende del tipo del objeto, por lo que la guía de estilo obliga a la delegación: el código de nivel de aplicación afirma arrogantemente que sabe mejor que el objeto sería la locura.
Además, X is Whatever
siempre, invariablemente significa que X es exactamente el mismo objeto que lo que sea. Hacer una excepción totalmente única para Empty
o cualquier otro valor específico de Whatever
que sea absurdo, es difícil imaginar un enfoque más antípónico. Y "ser exactamente el mismo objeto" es obviamente transitivo, por lo que ya no podría tener listas vacías, conjuntos vacíos, dictados vacíos ... felicidades, acaba de diseñar un lenguaje completamente inutilizable e inútil, donde cada contenedor vacío Locamente "colapsa" a un solo objeto contenedor vacío (solo imagine la diversión cuando alguien intenta mutar un contenedor vacío ...?!).
Estoy de acuerdo en que a veces if foo:
no es explícito para mí cuando realmente quiero decirle al lector el código que estoy probando es el vacío. En esos casos, uso if len(foo):
Suficientemente explícito
Estoy de acuerdo al 100% con que Alex Wrt is Empty
ser antipónico.
Hay un control de vacío explícito para iterables en Python. Se deletrea not
. ¿Qué hay implícito allí? not
da True cuando iterable está vacío, y da False cuando no está vacío.
¿A qué te opones exactamente? ¿Un nombre? Como otros te han dicho, es ciertamente mejor que is Empty
. Y no es tan poco dramático: considerando cómo se nombran las cosas en Python, podemos imaginar una secuencia llamada widgets
, que contiene, sorprendentemente, algunos widgets. Entonces,
if not widgets:
Se puede leer como "si no hay widgets ...".
¿O te opones a la longitud? Explícito no significa verboso, esos son dos conceptos diferentes. Python no tiene addition
método de addition
, tiene un operador +
, que es completamente explícito si conoce el tipo al que lo está aplicando. Lo mismo con el not
.
La razón por la que no hay un is Empty
es asombrosamente simple una vez que entiendes lo que hace el operador.
Del manual de python :
Los operadores
is
yis not
prueban la identidad del objeto:x is y
es verdadero si y solo six
ey
son el mismo objeto.x is not y
produce el valor de verdad inverso.
Eso significa que some_sequence is Empty
comprueba si some_sequence
es el mismo objeto que Empty
. Eso no puede funcionar como usted sugirió.
Considere el siguiente ejemplo:
>>> a = []
>>> b = {}
Ahora simulemos que hay una construcción is Empty
en python:
>>> a is Empty
True
>>> b is Empty
True
Pero dado que el operador es el control de identidad, eso significa que a
y b
son idénticos a Empty
. Eso, a su vez, debe significar que a
y b
son idénticos, pero no lo son:
>>> a is b
False
Entonces, para responder a tu pregunta "¿por qué no hay is Empty
en python?": Porque is
verifica la identidad.
Para tener la construcción is Empty
, debes hackear el operador para que signifique algo más o crear algún objeto Empty
mágico que de alguna manera detecte colecciones vacías y luego sea idéntico a ellas.
En lugar de preguntar por qué no hay un is Empty
, debe preguntar por qué no hay una función incorporada isempty()
que llame al método especial __isempty__()
.
Así que en lugar de usar booleanas implícitas:
if saved:
mess_up()
Tenemos cheque vacío explícito:
if not isempty(saved):
mess_up()
donde la clase de saved
tiene un __isempty__()
implementado en alguna lógica sana.
Encuentro eso mucho mejor que usar booleanas implícitas para el control de vacíos.
Por supuesto, puedes definir fácilmente tu propia función isempty()
:
def isempty(collection):
try:
return collection.__isempty__()
except AttributeError:
# fall back to implicit booleaness but check for common pitfalls
if collection is None:
raise TypeError(''None cannot be empty'')
if collection is False:
raise TypeError(''False cannot be empty'')
if collection == 0:
raise TypeError(''0 cannot be empty'')
return bool(collection)
y luego defina un __isempty__()
que devuelva un booleano para todas sus clases de colección.