Puedo usar:
if A:
en vez de
if A is not None:
Esto último parece muy detallado. ¿Hay una diferencia?
La declaración
if A:
llamará A.__nonzero__()
(consulte la documentación de nombres de métodos especiales ) y utilizará el valor de retorno de esa función. Aquí está el resumen:
object.__nonzero__(self)
Llamado a implementar pruebas de valor de verdad y la operación incorporada
bool()
; debe devolverFalse
oTrue
, o sus equivalentes enteros0
o1
. Cuando este método no está definido,__len__()
se llama, si está definido, y el objeto se considera verdadero si su resultado es distinto de cero. Si una clase no define ni__len__()
ni__nonzero__()
, todas sus instancias se consideran verdaderas.
Por otra parte,
if A is not None:
compara solo la referencia A
con None
para ver si es igual o no.
A is not None
es más rápido ya que hay mucho menos trabajo por hacerif object(): pass
es ~ 0.130 usec por ciclo, mientras queif object() is not None: pass
es ~ 0.135 usec. De todos modos, no debe usar el rendimiento para elegir entre estos dos, sino observar las diferencias en cómo funcionan, ya que no son equivalentes .if A is not None
parece ser más lento porque es una comparación y necesita cargar el singleton incorporadoNone
como un paso intermedio para compararA
(mira eldis.dis()
). Corrígeme si me equivoco peroif A:
parece ser más eficiente, tan pronto como realmente quieras probar el valor de verdad y no laNone
identidad.python -m timeit -s"a=0" "if a: pass" "else: pass"
es más rápido quepython -m timeit -s"a=0" "if a is None: pass" "else: pass"
peropython -m timeit -s"a=1" "if a: pass" "else: pass"
es más lento. Podría depender de la plataforma, vea si obtiene los mismos resultadosis None
prueba fue la más lenta para mí. En pypy, todos midieron exactamente lo mismo :)Como está escrito en PEP8 :
fuente
None
, sino solo en una verificación del valor de verdad. En este caso,if A:
parece más eficiente (tome undis.dis()
, hay los pasos adicionales de cargar el builtinNone
y compararif A is not None:
, mientras que solo hay unjump_if
en el otro caso).entonces no es lo mismo que
fuente
Muchas funciones devuelven Ninguno si no hay resultados apropiados. Por ejemplo, el
.first()
método de una consulta SQLAlchemy devuelve None si no había filas en el resultado. Suponga que está seleccionando un valor que podría devolver 0 y necesita saber si en realidad es 0 o si la consulta no tuvo ningún resultado.Una expresión común es dar a una función o argumento opcional de un método el valor predeterminado de Ninguno, y luego probar que ese valor sea Ninguno para ver si se especificó. Por ejemplo:
compara eso con:
En este último, ¿qué pasa si llamas
spam(0)
ospam([])
? La función detectaría (incorrectamente) que no ha pasado un valor paraeggs
y calcularía un valor predeterminado para usted. Eso probablemente no sea lo que quieres.O imagine un método como "devolver la lista de transacciones para una cuenta determinada". Si la cuenta no existe, podría devolver Ninguno. Esto es diferente a devolver una lista vacía (lo que significaría "esta cuenta existe pero no ha registrado transacciones).
Finalmente, de vuelta a las cosas de la base de datos. Hay una gran diferencia entre NULL y una cadena vacía. Una cadena vacía generalmente dice "hay un valor aquí, y ese valor no es nada". NULL dice "este valor no se ha ingresado".
En cada uno de esos casos, querrás usar
if A is None
. Está buscando un valor específico, Ninguno, no solo "cualquier valor que se convierta en False".fuente
Hacen cosas muy diferentes .
Las siguientes comprobaciones si A tiene nada, excepto los valores
False
,[]
,None
,''
y0
. Comprueba el valor de A.Lo siguiente verifica si A es un objeto diferente a Ninguno. Comprueba y compara la referencia (dirección de memoria) de A y Ninguna.
ACTUALIZACIÓN: explicación adicional
Muchas veces los dos parecen hacer lo mismo, por lo que mucha gente los usa indistintamente, es una muy mala idea. La razón por la que los dos dan los mismos resultados es muchas veces por pura coincidencia debido a optimizaciones del intérprete / compilador como pasantías u otra cosa.
Con esas optimizaciones en mente, los enteros y las cadenas del mismo valor terminan usando el mismo espacio de memoria. Eso probablemente explica por qué dos cadenas separadas actúan como si fueran lo mismo.
Sin embargo, otras cosas no se comportan igual ...
Las dos listas claramente tienen su propia memoria. Sorprendentemente, las tuplas se comportan como cuerdas.
Probablemente esto se deba a que se garantiza que las tuplas no cambiarán, por lo que tiene sentido reutilizar la misma memoria.
La conclusión es que no puedes confiar en las coincidencias . Solo porque grazna como un pato no significa que sea un pato. Use
is
y==
dependiendo de lo que realmente quiera verificar. Estas cosas pueden ser difíciles de depurar ya que seis
lee como una prosa que a menudo simplemente pasamos por alto.fuente
None
es un singleton, no es un detalle de implementación (a diferencia de int o string interning). No estoy seguro de seguir lo que quieres decir.None
comporte de manera diferenteint
ostr
debido a la internación. Mi punto es esois
y==
estoy revisando cosas diferentes; primero verifica una dirección de memoria, el segundo verifica el contenido de las direcciones de memoria.if A:
resultará falso si A es 0, Falso, cadena vacía, lista vacía o Ninguno, lo que puede conducir a resultados no deseados.fuente
La mayoría de las guías que he visto sugieren que debes usar
si A:
a menos que tenga una razón para ser más específico.
Hay algunas pequeñas diferencias. Hay valores distintos de None que devuelven False, por ejemplo, listas vacías, o 0, así que piense en qué es lo que realmente está probando.
fuente
Ninguno es un valor especial en Python que generalmente designa una variable no inicializada. Para probar si A no tiene este valor particular, utilice:
Los valores de Falsey son una clase especial de objetos en Python (por ejemplo, falso, []). Para probar si A es falsey, use:
Por lo tanto, las dos expresiones no son lo mismo Y será mejor que no las trates como sinónimos.
PD None también es falsey, por lo que la primera expresión implica la segunda. Pero el segundo cubre otros valores de falsey además de Ninguno. Ahora ... si puede estar seguro de que no puede tener otros valores de falsey además de Ninguno en A, puede reemplazar la primera expresión con la segunda.
fuente
Depende del contexto.
Lo uso
if A:
cuando esperoA
ser algún tipo de colección, y solo quiero ejecutar el bloque si la colección no está vacía. Esto le permite a la persona que llama pasar cualquier colección con buen comportamiento, vacía o no, y hacer que haga lo que espero. También permiteNone
yFalse
suprime la ejecución del bloque, que en ocasiones es conveniente para llamar al código.OTOH, si espero
A
ser un objeto completamente arbitrario pero podría haber sido predeterminadoNone
, entonces siempre lo usoif A is not None
, ya que el código de llamada podría haber pasado deliberadamente una referencia a una colección vacía, una cadena vacía o un tipo numérico con valor 0, o booleanoFalse
, o alguna instancia de clase que resulta ser falsa en contexto booleano.Y por otro lado, si espero
A
ser algo más específico (por ejemplo, una instancia de una clase a la que llamaré métodos), pero podría haber sido predeterminadoNone
, y considero que la conversión booleana predeterminada es una propiedad de la clase No me importa imponer en todas las subclases, luego usaréif A:
para salvar a mis dedos la terrible carga de escribir 12 caracteres adicionales.fuente
Creé un archivo llamado
test.py
y lo ejecuté en el intérprete. Puede cambiar lo que quiera, para probar con seguridad cómo están las cosas detrás de escena.Esta es la diferencia del ensamblador:
Fuente:
fuente
El primero es más Pitónico (mejor código ideomático), pero no ejecutará el bloque si A es Falso (no Ninguno).
fuente
is/is not None
. Siguiendo PEP8 es Pythonic. Además las dos pruebas son diferentes .python> = 2.6,
si escribimos como
generará advertencia como,
Entonces podemos usar
fuente