Ya sabemos que Python es un lenguaje de «tipado» dinámico, es decir, no es necesario inidicar de qué tipo de dato es una variable (siguiendo la nomenclatura de los lenguajes tradicionales; lo correcto en Python sería hablar de objetos: véase Diferencia entre variables en Python y otros lenguajes) al momento de crearla ni tampoco que la misma mantenga ese tipo de dato a lo largo de la ejecución del programa: puede comenzar siendo un entero, luego una cadena, luego un número de coma flotante, etc. No obstante, todas las variables tienen algún tipo de dato (para ser más precisos, en realidad, son instancias de alguna clase; pero esto no nos interesa para el presente artículo) que podemos conocer vía la función incorporada type()
:
>>> pi = 3.14 >>> type(pi) <class 'float'>
Los cuatro tipos de dato básicos son el número entero (int
), el número de coma flotante (float
), la cadena de caracteres (str
) y el booleano (bool
). Sin embargo, Python incorpora un quinto tipo de dato que estrictamente hablando se llama NoneType
y cuyo único valor posible es None
(pronunciado llanamente «nan»).
>>> a = None >>> type(a) <class 'NoneType'>
A menudo None
es utilizado cuando se quiere crear una variable (puesto que Python no distingue la creación de la asignación: crear una variable es simplemente darle un valor) pero aún no se le quiere asignar ningún valor en particular; aunque, en definitiva, como dijimos, None
es también un valor. No debe ser interpretado como el valor NULL
de lenguajes como C y C++, que solo se aplica a punteros; antes bien, None
puede ser asignado a cualquier objeto.
# Una variable puede empezar siendo `None` y luego ser asignada con otro valor. >>> a = None >>> type(a) <class 'NoneType'> >>> a = "Hola mundo" >>> type(a) <class 'str'> # O viceversa, empezar con un valor y luego ser asignada con `None`. >>> b = 5 >>> b = None
Nótese que cuando escribimos el nombre de una variable en la consola interactiva cuyo contenido es None
, no se mostrará nada.
>>> a = None >>> a >>>
Dado que se trata de un tipo de dato como cualquier otro, con la peculiaridad de que tiene un único valor posible, podemos realizar las comparaciones habituales.
a = None if a == None: print("a es None.") else: print("a no es None.")
Si bien esto es válido, la forma recomendada de hacer comparaciones con este tipo de dato es utilizando la palabra reservada is
(véase más abajo la explicación técnica de esto).
a = None # Método recomendado de comparación. if a is None: print("a es None.") else: print("a no es None.")
O bien para chequear si una variable no es None
:
a = 1 b = 2 # Válido. if not a is None: print("a no es None.") # Válido y más legible. if b is not None: print("b no es None.")
Las dos comparaciones son similares, pero la segunda es la más recomendada.
Ejemplos
¿En qué casos es útil emplear None
? Ya dijimos que es particularmente provechoso cuando queremos crear un variable pero no asignarle ─por el momento─ ningún valor. Por ejemplo, el siguiente código busca la cadena "Python"
en una lista de lenguajes e imprime su posición, en caso de encontrarla:
lenguajes = ["C", "C++", "Python", "Java", "Go"] posicion = None for i, elemento in enumerate(lenguajes): if elemento == "Python": posicion = i break if posicion is None: print("No se encontró el elemento.") else: print("El elemento está en la posición:", i)
Aquí definimos posicion
inicialmente como None
, ya que puede ocurrir que el elemento buscado no se encuentre en la lista. Si el valor sigue siendo ese luego de la ejecución del bucle, quiere decir que el elemento no se ha encontrado. El valor inicial no podría ser cero, porque el cero es un índice válido (el primer elemento). Tampoco -1
, porque los elementos de una lista también pueden ser accedidos en sentido inverso (-1
es el último, -2
el penúltimo, etc.). Vemos que None encaja perfecto para esta tarea.
Asimismo None
es particularmente útil al definir argumentos con valores por defecto. Supongamos una función que toma como argumento una lista e imprime cada uno de los elementos en pantalla.
def imprimir(lista): for elemento in lista: print(elemento) imprimir([1, 2, 3, 4])
Pero ahora queremos que si el usuario no indica ninguna lista como argumento, imprima las líneas de un archivo de texto. Asignándole None
como valor por defecto a lista
, podremos saber en el interior de la función si el argumento fue provisto por el usuario.
def imprimir(lista=None): if lista is not None: for elemento in lista: print(elemento) else: with open("mi-archivo.txt") as f: print(f.read())
Explicación técnica
Para los interesados, la explicación técnica de por qué las comparaciones se realizan usando la partícula is
es la siguiente: solamente existe un objeto None
almacenado en memoria, y todas las variables que tengan este valor no son sino «punteros» a esa dirección de memoria. Podemos comprobar esto usando la función incorporada id()
, que retorna la dirección de memoria de un objeto (nótese que es el mismo número).
>>> a = None >>> b = None >>> id(a) 1636093900 >>> id(b) 1636093900
La palabra reservada is
lo que hace es, justamente, comparar las direcciones de memoria de dos objetos, una operación mucho más rápida que las efectuadas con la igualdad (==
) y desigualdad (!=
), que implican llamar al método mágico __eq__()
de uno de los objetos de la comparación.
Curso online 👨💻
¡Ya lanzamos el curso oficial de Recursos Python en Udemy!
Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter
en 2024.
Consultoría 💡
Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.
Orlando says:
Claro y preciso. Buena publicación
Abelardo says:
Buen artículo, por cierto. Muchas gracias.
Abelardo says:
En el ejemplo que se expone en este artículo para encontrar la cadena Python en la lista, una alternativa a usar el bucle for es usar el while:
lenguajes = [«C», «Python», «Ada», «Java»]
encontrado = False
i = 0
numElementos = len (lenguajes)
while i < numElementos and not encontrado:
if lenguajes[i] == "Python":
encontrado = True
else:
i=i+1
if encontrado:
print ("Fue encontrado")
else:
print ("No fue encontrado")