Comprendiendo el comportamiento de los objetos de Python
Recuerda que en Python los tipos de datos son objetos. Por ejemplo,
str
,int
,list
,bool
, etc.
¡Atención! En este capítulo se habla de ciertas estructuras como diccionarios y conjuntos, los cuales no están explicados aún. No te preocupes por ello, no te has perdido nada.
Estas estructuras son otros tipos de datos de Python, como los
int
,float
,bool
... pero más complejos.
Espacio publicitario
Mutabilidad
Los objetos mutables (cambiantes) son aquellos cuyos valores internos pueden ser modificados después de su creación.
Algunos ejemplos de objetos mutables son:
list
, dict
y set
.
Por ejemplo, puedo crear la siguiente lista, y modificar alguno de sus valores posteriormente:
lista = [10, 10, 30, 40]
# Reasigna el valor 20 a la posición 1 de la lista
lista[1] = 20
print(lista)
[10, 20, 30, 40]
Parte del objeto ha sido modificado, sin sustituirlo completamente por otro. Esto es lo que demuestra la mutabilidad.
Espacio publicitario
Inmutabilidad
Los objetos inmutables (no cambiantes) son aquellos cuyos valores internos no pueden ser modificados después de su creación.
Algunos ejemplos de objetos mutables son:
int
, float
, str
y
tuple
.
Por ejemplo, puedo crear la siguiente tupla, pero no es posible modificar alguno de sus valores posteriormente:
tupla = (10, 10, 30, 40)
# Intenta reasignar el valor 20 a la posición 1 de la tupla
tupla[1] = 20
print(tupla)
TypeError: 'tuple' object does not support item assignment
Error de tipo: el objeto de tipo 'tupla' no admite la asignación de elementos
No he podido modificar los valores del objeto. Esto demuestra la inmutabilidad.
Puede que aquí tengas una duda con la inmutabilidad de los
tipos de datos como son float
,
int
o str
, los cuales habrás
reasignado en múltiples ocasiones.
Realmente, no los has modificado o mutado, lo que has hecho realmente es reemplazar un objeto por otro. Observa el siguiente ejemplo:
saludo = "Hola"
print(saludo[0])
print(saludo[1])
print(saludo[2])
print(saludo[3])
H
o
l
a
Una cadena de caracteres tiene índice de posición, como las listas. Cada caracter puede ser accedido individualmente.
Estas posiciones de la cadena son de solo lectura. Al ser
el str
inmutable, no puedes reasignar valores
a una posición concreta como harías con una lista.
Funcionan como las tuplas en cuanto inmutabilidad:
saludo = "Hola"
saludo[0] = "h"
TypeError: 'str' object does not support item assignment
Error de tipo: el objeto de tipo 'str' no admite la asignación de elementos
El error es el mismo que con las tuplas.
Si que puedes reemplazar una cadena por otra, pero será realmente otra, no habrás modificado la cadena en sí. Habrás modificado el estado de la variable.
saludo = "Hola"
saludo = "Adiós"
print(saludo)
Adiós
Espacio publicitario
Hashabilidad
Para que un objeto sea hashable, debe ser inmutable, tener un valor de hash constante en tiempo de ejecución y que sea comparable con otros objetos de su tipo para determinar si son iguales.
En Python, un hash es un valor entero que se obtiene al
aplicar la función hash()
a un objeto, y se
utiliza para identificar ese objeto en estructuras como
diccionarios o conjuntos.
Para que un objeto en Python sea "hashable" (es decir, que
se le pueda aplicar un hash), debe cumplir dos requisitos:
tener un valor inmutable y definir los métodos
__hash__()
y __eq__()
.
Por ejemplo, los tipos inmutables de Python, como los números, cadenas, y tuplas, son hashables, lo que permite usarlos como claves en diccionarios o elementos en conjuntos. Sin embargo, los tipos mutables, como las listas o los diccionarios, no son hashables y no pueden ser usados directamente en esas estructuras.
¿Por qué la necesidad de un hash?
El uso de un hash es necesario en programación para mejorar la velocidad y eficiencia al almacenar y buscar datos. Sin un hash, encontrar un elemento concreto en una lista larga de datos podría requerir revisar cada elemento uno por uno, lo cual es lento cuando la cantidad de datos es grande.
Los hashes permiten a estructuras como diccionarios y
conjuntos organizar los datos de manera que se pueda
acceder a ellos casi instantáneamente, sin importar
cuántos elementos haya. Cada dato se convierte en un valor
de hash que apunta directamente a su ubicación en memoria,
haciendo que las búsquedas y accesos sean mucho más
rápidos.
Además, los hashes también sirven para verificar la
integridad de los datos y almacenar contraseñas de manera
segura, ya que cualquier cambio en los datos originales
genera un hash distinto.
¿Por qué no se pueden utilizar objetos mutables como hash?
Los objetos mutables no pueden usarse como hash en Python
porque su valor puede cambiar con el tiempo, lo cual
rompería la consistencia del hash. La función
hash()
genera un valor único basado en el contenido del objeto, y
este valor se usa para organizar y acceder rápidamente a
los elementos en estructuras como diccionarios y
conjuntos.
Si el contenido de un objeto mutable cambiara después de
haber sido hashado, el valor del hash ya no coincidiría
con la ubicación donde se almacenó originalmente en la
estructura, lo que causaría problemas para encontrar y
acceder a los datos correctamente.
Por eso, solo los objetos inmutables, que garantizan que su contenido no cambiará, son aptos para usarse como claves en diccionarios o elementos en conjuntos.
Ver el número hash de un objeto
Para salir de dudas de si un objeto tiene hash o no,
puedes utilizar la función predefinida
hash()
de Python.
En el siguiente ejemplo, vamos a comprobarlo con un
str
:
saludo = "Hola"
# Imprime el hash del objeto
print(hash(saludo))
7566188970113123530
El número que aparece en la consola, es el hash que tiene el objeto (no tiene que salirte el mismo número que a mí).
Cada vez que ejecutes el programa se asignará un hash diferente al objeto.
Ahora, comprobemos sin un objeto como una lista, que incumple la regla de inmutabilidad, tiene hash o no:
numeros = [10, 20, 30]
print(hash(numeros))
TypeError: unhashable type: 'list'
Error de tipo: el objeto de tipo 'list' no es hashable
El error demuestra que el tipo de dato
list
, no tiene un hash, por lo tanto, no es un objeto hashable.
Todavía es pronto para desarrollar algo más complejo con los hash, pero esto te servirá para entender mejor como funcionan los conjuntos de Python, tema que explicaré en el siguiente capítulo.
Espacio publicitario
Iterabilidad
La iterabilidad es la capacidad de un objeto en ser recorrido con posiciones de índice. Por ejemplo, una lista, una tupla o una cadena, son objetos iterables, porque tienen índice de posición.
La forma más fácil de comprobar si un objeto es iterable, es intentar utilizar su índice de posición:
numeros = [10, 20, 30]
# Imprime la posición 0 de la lista
print(numeros[0])
10
Un objeto como un int
, no es iterable. Es un
objeto con un valor simple, que no tiene posiciones en un
índice:
numero = 10
print(numero[0])
TypeError: 'int' object is not subscriptable
Error de tipo: el objeto de tipo 'int' no es subscriptible
Lo que nos quiere indicar el error, es que este tipo de objeto no es accesible mediante índice de posición. No es iterable.
Haz las mismas comprobaciones mostradas en este capítulo, con cualquier tipo de objeto de Python. De esa forma sabrás de qué manera funciona cada uno.
Espacio publicitario
Espacio publicitario
Espacio publicitario