¿Qué es el método __init__?
El método __init__
es un método especial de
Python, que podemos incluir en las clases. Por norma
general, encontraremos este método en cada clase.

El nombre del método
__init__
tiene dos guiones bajos delante delinit
, y dos más después. Si pones solo uno en cada lado, no te va a funcionar.
El nombre del método
__init__
proviene de la palabra en inglés denominada como initialize, que en español significa inicializar.
Espacio publicitario
¿Para qué sirve el método __init__?
El método __init__
es un método que no
necesita ser llamado explícitamente. Este método se llama
automáticamente por parte del intérprete de Python, al
crear una instancia de una clase (hablo en tiempo de
ejecución, no me refiero a cuando escribes el código).
Gracias a este método constructor, podrás dar un estado inicial al objeto.
Veamos un ejemplo práctico para aclarar este concepto teórico.
La siguiente clase Usuario
, está funcionando
correctamente:
class Usuario:
# Atributos
nombre = "Sin nombre"
apellidos = "Sin apellidos"
edad = 0
direccion = "Sin dirección"
telefono = "Sin teléfono"
# Métodos
def iniciar_sesion(self):
print("El usuario ha iniciado sesión")
def cerrar_sesion(self):
print("El usuario ha cerrado sesión")
def cambiar_nombre_perfil(self):
print("Se cambió el nombre")
No obstante, ¿cómo harías para crear tres objetos con esta clase, e inicializar todos sus atributos?
Tendrías que ir reasignando uno por uno.
Aquí tienes un ejemplo con un solo objeto:
# Instanciación
usuario_1 = Usuario()
# Inicialización de datos
usuario_1.nombre = "Enrique"
usuario_1.apellidos = "Barros Fernández"
usuario_1.edad = 32
usuario_1.direccion = "C/Programación Fácil n.º 34"
usuario_1.telefono = "123456789"
Ahora, haz esto mismo con dos objetos más, o con el número que sea, por ejemplo, 500. Son muchas líneas, ¿verdad?
Para mejorar este proceso de construcción inicial de los
objetos, se creó el método __init__
. Gracias
a él, podrás dar un estado inicial de una forma muy
sencilla y práctica.
Atributos de clase y de instancia
Estos atributos de clase dan un mismo valor a todos los
objetos instanciados. Por ejemplo, si instancio dos
objetos de tipo Usuario
, estaré creando dos
objetos con el valor "Sin nombre"
, en el
atributo nombre
.
Mientras que con los atributos de instancia, podrán ser diferentes desde un principio, en cada objeto.
Esto lo irás entendiendo mejor con los siguientes ejemplos.
Espacio publicitario
Añadir el método __init__ a una clase
Vamos a sustituir en el ejemplo anterior, todos los
atributos de clase, por atributos de instancia, utilizando
el método __init__
:
class Usuario:
def __init__(self, nombre, apellidos, edad, direccion, telefono):
self.nombre = nombre
self.apellidos = apellidos
self.edad = edad
self.direccion = direccion
self.telefono = telefono
# Métodos
def iniciar_sesion(self):
print("El usuario ha iniciado sesión")
def cerrar_sesion(self):
print("El usuario ha cerrado sesión")
def cambiar_nombre_perfil(self):
print("Se cambió el nombre")
¡Genial!, ya tenemos el método __init__
listo
para construir objetos.
Por el momento, hasta que lo explique, ignora completamente el parámetro
self
. Simplemente, sigue poniéndolo en los paréntesis de los métodos.
Ahora, creemos un objeto a partir de la clase. Esta vez, en lugar de inicializar cada atributo de la forma que has visto en el ejemplo anterior, lo haremos así, de una forma mucho más eficiente:
# Instancia
usuario_1 = Usuario("Enrique",
"Barros Fernández",
32,
"C/Programación Fácil n.º 34",
"123456789")
# Probamos un atributo
print(usuario_1.nombre)
Enrique
En Python, entre los paréntesis, puedes colocar los elementos con saltos de línea y tabulaciones, ya que estos no afectan al intérprete.
Gracias al método __init__, podemos dar un estado inicial a los atributos de los objetos en la propia instanciación.
Al crearse el objeto, Python llama automáticamente al método. Esto ocurre porque es un método especial. No tenemos que llamarlo nosotros, tal y como he indicado anteriormente.
Al crear un objeto de una clase, que tiene método
__init__
, se hace una llamada implícita. Lo
llama el intérprete de Python internamente.
Fíjate que los argumentos utilizados en el ejemplo, son
posicionales (deben seguir el orden de declaración del
__init__
). No obstante, puedes utilizar
argumentos de clave:
usuario_1 = Usuario(apellidos = "Barros Fernández",
edad = 32,
direccion = "C/Programación Fácil n.º 34",
telefono = "123456789",
nombre = "Enrique")
En este caso, el orden no importa.
¿Qué ocurre si no quiero inicializar un atributo en la instancia?
Supongamos que quiero inicializar de momento solo el
atributo nombre
, y el resto no.
Entonces, ocurrirá la siguiente excepción:
# Instancia
usuario_1 = Usuario(nombre = "Enrique")
TypeError: Usuario.__init__() missing 4 required positional arguments: 'apellidos', 'edad', 'direccion', and 'telefono'
Error de tipo: Faltan 4 argumentos posicionales obligatorios en el método init() de la clase Usuario: 'apellidos', 'edad', 'direccion', y 'telefono'
Como es lógico, al igual que con las funciones, si tenemos cinco parámetros, hay que escribir cinco argumentos en la llamada. Entonces quiere decir que el método
__init__
nos obliga a inicializar los objetos con los parámetros que se especifiquen en él.
Espacio publicitario
Si en la clase quieres tener también atributos de clase, junto a los de instancia, los puedes tener perfectamente. Estos funcionan de forma independiente al método constructor.
Aquí tienes un ejemplo usando un atributo de clase y los de instancia a la vez:
class Usuario:
# Atributos de clase
hora_ultimo_inicio = None
# Atributos de instancia
def __init__(self, nombre, apellidos, edad, direccion, telefono):
self.nombre = nombre
self.apellidos = apellidos
self.edad = edad
self.direccion = direccion
self.telefono = telefono
En este ejemplo, cuando instanciemos un objeto de esta
clase, le tendremos que dar los cinco valores
obligatorios; los iniciales. Pero el atributo de clase
hora_ultimo_inicio
, tendrá por defecto ese
valor None, que podrá ser reasignado posteriormente, al
igual que cualquier atributo del __init__
.
Sin embargo, sin reasignaciones sobre el propio atributo
hora_ultimo_inicio
, no le podemos dar un
estado inicial diferente para cada objeto, solo lo
controlamos después con la reasignación.
En el siguiente ejemplo, se muestra cómo se da un estado
inicial a los atributos de instancia, cómo se reasigna uno
de ellos (nombre
) y cómo se reasigna el
atributo de clase (hora_ultimo_inicio
).
# Estado inicial a los atributos de instancia
usuario_1 = Usuario("Enrique",
"Barros Fernández",
32,
"C/Programación Fácil n.º 34",
"123456709")
# Reasignaciones
usuario_1.nombre = "Quique"
usuario_1.hora_ultimo_inicio = ("20/12/2025")
# Probamos los atributos
print(usuario_1.nombre)
print(usuario_1.hora_ultimo_inicio)
Quique
20/12/2025
Nombres en el __init__
Puede ser que no veas clara la diferenciación entre lo que
son los nombres de atributo, y los nombres de parámetro en
la declaración del __init__
.
En el siguiente ejemplo, podrás ver una clara diferencia entre ambos:
def __init__(self, parametro_1, parametro_2, parametro_3, parametro_4, parametro_5):
self.atributo_1 = parametro_1
self.atributo_2 = parametro_2
self.atributo_3 = parametro_3
self.atributo_4 = parametro_4
self.atributo_5 = parametro_5
Cuando instanciamos y damos los valores iniciales con
argumentos, estos se pasan a los parámetros del
__init__
. Tales valores se van asignando a
los atributos correspondientes, tal y como puedes ver en
el ejemplo.
Lo que quiero dejar claro, es que no tiene porqué ponerse el mismo nombre de atributo que de parámetro.
Espacio publicitario
Puedes escribir un __init__
como el del
ejemplo de código. Este va a funcionar correctamente.
No obstante, normalmente, verás escrito el mismo nombre de atributo que de parámetro. Esto con el fin de dejar claridad en el código.
Valores por defecto en el __init__
Otra posibilidad es la de tener valores iniciales por
defecto en el propio __init__
.
Se trata de dejar atributos inicializados de la siguiente
forma (fíjate en el atributo direccion
):
class Usuario:
# Atributos de instancia
def __init__(self, nombre, apellidos, edad, telefono):
self.nombre = nombre
self.apellidos = apellidos
self.edad = edad
self.telefono = telefono
self.direccion = "Sin dirección"
Si dejamos valores por defecto en ciertos atributos de instancia, no será necesario añadir el valor correspondiente en la instanciación.
Según el código de ejemplo, todos los objetos, serán
instanciados con ese valor "Sin dirección"
,
por defecto en el atributo direccion
.
Ten en cuenta, que en este caso no se está pasando el atributo
direccion
como parámetro del__init__
, ya que lo estamos inicializando directamente desde la clase.
Espacio publicitario
Espacio publicitario
Espacio publicitario