Geekflare recibe el apoyo de nuestra audiencia. Podemos ganar comisiones de afiliación de los enlaces de compra en este sitio.
En Desarrollo Última actualización: 25 de septiembre de 2023
Compartir en:
Escáner de seguridad de aplicaciones web Invicti - la única solución que ofrece verificación automática de vulnerabilidades con Proof-Based Scanning™.

¿Quiere iniciarse en el diseño orientado a objetos en Python? Dé los primeros pasos hoy aprendiendo sobre el método __init__ de Python.

En este tutorial, repasaremos los fundamentos de las clases y objetos de Python, para luego proceder a aprender sobre el método __init__.

Al final de este tutorial, será capaz de responder a las siguientes preguntas:

  • ¿Qué son las variables de instancia o atributos de instancia?
  • ¿Cómo ayuda el método init a inicializar los atributos de instancia?
  • ¿Cómo podemos establecer valores por defecto para los atributos?
  • ¿Cómo podemos utilizar los métodos de clase como constructores para crear objetos?

Empecemos.

Clases y objetos en Python

Las clases son fundamentales para la programación orientada a objetos en Python. Podemos crear una clase y definir atributos y métodos paraunir datos y funcionalidad asociada.

Una vez que hayamos creado una clase, podemos utilizarla como un plano (o una plantilla) para crear objetos (instancias).

👩‍🏫Example ¡hora! Creemos una clase Empleado en la que cada objeto de esta clase tenga los siguientes atributos

  • full_name: el nombre completo del empleado en el formato firstName lastName
  • emp_id: el id del empleado
  • departamento: el departamento al que pertenecen
  • experience: el número de años de experiencia que tienen
Clases y objetos Python

¿Qué significa esto? 🤔

Cada empleado individual será una instancia u objeto de la clase Empleado. Y cada objeto tendrá su propio valor para nombre_completo, emp_id, departamento y experiencia.

Estos atributos también se denominan variables de instancia, y utilizaremos los términos atributos y variables de instancia indistintamente.

Objetos Python

Llegaremos a la adición de atributos en un momento. Por ahora crearemos una clase Empleado de la siguiente manera

class Empleado:
 pass

El uso de pass (como marcador de posición) nos ayuda a evitar errores cuando ejecutamos el script.

Aunque la versión actual de la clase Empleado no es muy útil, sigue siendo una clase válida. Así podemos crear objetos de la clase Empleado:

empleado_1 = Empleado()

print(empleado_1)
#Salida: <__objeto principal__.Empleado en 0x00FEE7F0&gt

También podemos añadir atributos e inicializarlos con valores como se muestra:

employee_1.full_name = 'Amy Bell'
employee_1.department = 'HR'

Pero este enfoque para añadir atributos de instancia es ineficaz y propenso a errores. Además, esto no permite utilizar la clase como plantilla para crear objetos. Aquí es donde el método __init__ ayuda.

Comprender el papel del método __init__ en una clase Python

Método en una clase de Python

Debemos ser capaces de inicializar las variables de instancia al instanciar un objeto y el método __init__ nos ayuda a hacerlo. El método __init__ es llamado cada vez que se crea un nuevo objeto de la clase para inicializar los valores de las variables de instancia.

Si ha programado en un lenguaje como C , verá que el método __init__ funciona de forma similar a los constructores.

Definición del método __init__

Añadimos el método __init__ a la clase Empleado:

class Empleado:
 def __init__(self, nombre_completo,emp_id,departamento,experiencia):
 self.nombre_completo = nombre_completo
 self.emp_id = emp_id
 self.departamento = departamento
 self.experiencia = experiencia

El parámetro self hace referencia a la instancia de la clase, y self.attribute inicializa el atributo de la instancia con el valor de la parte derecha.

Ahora podemos crear objetos de la siguiente manera

empleado_2 = Empleado('Bella Joy','M007','Marketing',3)
print(empleado_2)
# Salida: <__main__.Objeto empleado en 0x017F88B0&gt

Cuando imprimimos los objetos empleados, no obtenemos ninguna información útil excepto la clase a la que pertenecen. Añadimos un método __repr__ que defina una cadena de representación para la clase:

 def __repr__(self):
 return f"{self.nombre_completo},{self.emp_id} de {self.departamento} con {self.experiencia} años de experiencia."

Añadiendo el __repr__ a la clase Empleado, tenemos:

class Empleado:
 def __init__(self, nombre_completo,emp_id,departamento,experiencia):
 self.nombre_completo = nombre_completo
 self.emp_id = emp_id
 self.departamento = departamento
 self.experiencia = experiencia
    
 def __repr__(self):
 return f"{self.nombre_completo},{self.emp_id} de {self.departamento} con {self.experiencia} años de experiencia."

Ahora los objetos empleados tienen una cadena de representación útil:

print(empleado_2)
# Salida: Bella Joy,M007 de Marketing con 3 años de experiencia.

Algunas convenciones

Antes de seguir adelante, he aquí un par de notas:

  • Utilice self como primer parámetro en el método __init__ para referirnos a la propia instancia de la clase y utilizamos self.nombre_atributo para inicializar los distintos atributos. Utilice self es la convención preferida (aunque puede utilizar cualquier otro nombre).
  • Al definir el método __init__, establecemos los nombres de los parámetros en las definiciones __init__ para que coincidan con los nombres de los atributos. Esto mejora la legibilidad.

Cómo añadir valores por defecto a los atributos

Cómo añadir valores por defecto a los atributos

En el ejemplo que hemos codificado hasta ahora, todos los atributos son obligatorios. Lo que significa que la creación del objeto sólo tiene éxito si pasamos los valores de todos los campos al constructor.

Intente instanciar un objeto de la clase Empleado sin pasar el valor para el atributo experiencia:

empleado_3 = Empleado('Jake Lee','E001','Ingeniería')

Obtendrá el siguiente error:

Traceback (most recent call last):
 File "main.py", line 22, in <module>
 empleado_3 = Empleado('Jake Lee','E001','Ingeniería')
TypeError: __init__() missing 1 required positional argument: 'experience'

Pero si desea que ciertos atributos sean opcionales, puede hacerlo proporcionando valores por defecto para esos atributos al definir el método __init__.

Aquí proporcionamos un valor por defecto de 0 para el atributo experiencia:

class Empleado:
 def __init__(self, nombre_completo,emp_id,departamento,experiencia=0):
 self.nombre_completo = nombre_completo
 self.emp_id = emp_id
 self.departamento = departamento
 self.experiencia = experiencia
    
 def __repr__(self):
 return f"{self.nombre_completo},{self.emp_id} de {self.departamento} con {self.experiencia} años de experiencia."

El objeto empleado_3 se crea sin valor para el atributo experiencia; se utiliza el valor por defecto 0 para la experiencia.

empleado_3 = Empleado('Jake Lee','E001','Ingeniería')
print(empleado_3.experiencia)
# Salida: 0

Constructores de clase alternativos utilizando métodos de clase

Constructores alternativos de clases que utilizan métodos de clase

Hasta ahora sólo hemos visto cómo definir el método __init__ y establecer valores por defecto para los atributos cuando sea necesario. También sabemos que necesitamos pasar los valores para los atributos requeridos en el constructor.

A veces, sin embargo, los valores para estas variables de instancia (o atributos) pueden estar disponibles en una estructura de datos diferente, como una tupla, un diccionario o una cadena JSON.

Entonces, ¿qué hacemos?

Pongamos un ejemplo. Supongamos que tenemos valores de la variable de instancia en un diccionario Python:

dict_fanny = {'nombre':'Fanny Walker','id':'H203','dept':'RRHH','exp':2}

Podemos acceder al diccionario y obtener todos los atributos así

nombre = dict_fanny['nombre']
id = dict_fanny['id']
dept = dict_fanny['dept']
exp = dict_fanny['exp']

Después de esto puede crear un objeto pasando estos valores al constructor de la clase:

empleado_4 = Empleado(nombre, id, depto, exp)
print(empleado_4)
# Salida: Fanny Walker,H203 de RRHH con 2 años de experiencia.

Recuerde: tiene que hacer esto para cada nuevo objeto que cree. Este enfoque es ineficiente y sin duda podemos hacerlo mejor. ¿Pero cómo?

En Python, podemos utilizar métodos de clase como constructores para crear objetos de la clase. Para crear un método de clase utilizamos el decorador @classmethod.

Definamos un método que analice el diccionario, obtenga los valores de las variables de instancia y los utilice para construir objetos Empleado.

   @classmethod
 def from_dict(cls,data_dict):
 full_name = data_dict['name']
 emp_id = data_dict['id']
 department = data_dict['dept']
 experience = data_dict['exp']
 return cls(full_name, emp_id, department, experience)

Cuando necesitemos crear objetos utilizando datos del diccionario, podemos utilizar el método de clase from_dict().

💡 Observe el uso de cls en el método de clase en lugar de self. Del mismo modo que utilizamos self para referirnos a la instancia, cls se utiliza para referirnos a la clase. Además, los métodos de clase están ligados a la clase y no a los objetos.

Así que cuando llamamos al método de clase from_dict() para crear objetos, lo hacemos sobre la clase Empleado:

emp_dict = {'name':'Tia Bell','id':'S270','dept':'Sales','exp':3}
employee_5 = Employee.from_dict(emp_dict)
print(employee_5)
# Salida: Tia Bell,S270 de Ventas con 3 años de experiencia.

Ahora, si tenemos un diccionario para cada uno de los n empleados, podemos utilizar el método de clase from_dict ( ) como constructor para instanciar en objetos, sin tener que recuperar los valores de las variables instantáneas del diccionario.

📝Atención a las variables de clase

Aquí definimos el método de clase que está ligado a la clase y no a instancias individuales. De forma similar a los métodos de clase, también podemos tener variables de clase.

Al igual que los métodos de clase, las Las variables de clase están ligadas a la clase y no a una instancia. Cuando un atributo toma un valor fijo para todas las instancias de la clase, podemos considerar definirlas como variables de clase.

Preguntas frecuentes

1. ¿Por qué es necesario el método __init__ en Python?

El método __init__ en la definición de una clase nos permite inicializar los atributos o variables de instancia de todas las instancias de la clase. El método __init__ es llamado cada vez que se crea una nueva instancia de la clase.

2. ¿Puede tener múltiples métodos __init__ en una clase Python?

El objetivo de tener múltiples métodos __init__ en una clase Python es proporcionar múltiples constructores que instancien objetos. Pero no puede definir múltiples métodos __init__. Si define múltiples métodos __init__la segunda y más reciente implementación sobrescribirá a la primera. Sin embargo, puede utilizar el decorador @classmethod para definir métodos de clase que puedan utilizarse como constructores para instanciar objetos.

3. ¿Qué ocurre si no se define el método __init__ en una clase?

Si no define el método __init__, aún podrá instanciar objetos. Sin embargo, tendrá que añadir manualmente variables de instancia y asignar valores a cada una de ellas. No podrá pasar los valores de las variables de instancia en el constructor. Esto no sólo es propenso a errores, sino que también anula el propósito de tener la clase como un plano a partir del cual podemos instanciar objetos.

4. ¿Se pueden ¿tener valores por defecto para los argumentos en el método __init__?

Sí, es posible proporcionar valores por defecto para uno o más atributos al definir el método __init__. Proporcionar valores por defecto ayuda a que esos atributos sean opcionales en el constructor. Los atributos toman los valores por defecto cuando no pasamos los valores para estos atributos en el constructor.

5. ¿Se ¿pueden modificar los atributos fuera del método __init__?

Sí, siempre puede actualizar el valor de un atributo fuera del método __init__. También puede añadir nuevos atributos dinámicamente a una instancia después de haberla creado.

Conclusión

En este tutorial, hemos aprendido a utilizar el método __init__ para inicializar los valores de las variables de instancia. Aunque esto es sencillo, puede resultar repetitivo, especialmente cuando se tienen muchos atributos.

Si está interesado, puede explorar el módulo dataclasses. En Python 3.7 y posteriores, puede utilizar el módulo incorporado de clases de datos para crear clases de datos que almacenen datos. Además de las implementaciones por defecto de __init__ y otros métodos de uso común; vienen con un montón de características interesantes para sugerencias de tipo, valores por defecto complejos y optimización.

A continuación, aprenda más sobre if __name__=='__main__' es Python.

  • Bala Priya C
    Autor
  • Narendra Mohan Mittal
    Editor

    Narendra Mohan Mittal es un versátil y experimentado estratega de marca digital y editor de contenidos con más de 12 años de experiencia. Es medalla de oro en M-Tech y B-Tech en Informática e Ingeniería.


    Actualmente,... Seguir leyendo

Gracias a nuestros patrocinadores
Más lecturas sobre desarrollo
Potencia tu negocio
Algunas de las herramientas y servicios que le ayudarán a hacer crecer su negocio.
  • Invicti utiliza el Proof-Based Scanning™ para verificar automáticamente las vulnerabilidades identificadas y generar resultados procesables en tan solo unas horas.
    Pruebe Invicti
  • Web scraping, proxy residencial, gestor de proxy, desbloqueador web, rastreador de motores de búsqueda, y todo lo que necesita para recopilar datos web.
    Pruebe Brightdata
  • Monday.com es un sistema operativo de trabajo todo en uno que te ayuda a gestionar proyectos, tareas, trabajo, ventas, CRM, operaciones, flujos de trabajo y mucho más.
    Prueba Monday
  • Intruder es un escáner de vulnerabilidades en línea que encuentra puntos débiles de ciberseguridad en su infraestructura, para evitar costosas violaciones de datos.
    Prueba Intruder