Constructores
El método __init__ es el encargado de fungir como constructor es decir que este va a inicializar una serie de atributos y ejecutar el código que le definamos al momento de que se cree un objeto de la clase, al ser llamado “__init__” con dos guiones bajos al inicio y final de la palabra init entonces ya tiene la sintaxis adecuada para que Python lo tome como un método “mágico” y sepa que debe ejecutarse al momento de hacer una instancia de la clase.
Lo que el constructor logra es que en vez de realizar lo siguiente para inicializar un objeto:
>>> f = FooBar() >>> f.init()
Ya colocando este código el objeto haya inicializado sus atributos solamente utilizando:
>>> f = FooBar()
Como se puede observar es un ahorro importante al momento de codificar y una ayuda por si olvidamos inicializar el objeto.
Creando el constructor
Crear el constructor en Python es bastante sencillo solo debemos definir el método y agregar que se debe realizar cuando se cree el objeto, veamos un ejemplo:
En la imagen se ve el método definido y en lo que debe ejecutar observamos que define el atributo somevar y lo iguala a 42. Veamos un ejemplo de cómo correría un objeto de esta clase:
En la imagen vemos que ya al momento de definir el objeto f del tipo FooBar queda inicializado y al acceder a su atribuyo somevar imprime 42 que es el valor definido en el constructor.
Ahora que pasa si queremos que los atributos se incialicen dinámicamente, reescribamos el método de la siguiente forma:
class FooBar: def __init__(self, value=42): self.somevar = value
Haciendo el parámetro opcional podemos pasar un valor, en caso que no lo pasemos tomará 42 como valor por defecto.
La ejecución del programa sería de la siguiente forma:
>>> f = FooBar('This is a constructor argument') >>> f.somevar 'This is a constructor argument'
De esta forma hemos hecho dinámico nuestro constructor por lo que podemos asignar atributos diferentes a nuestros objetos dependiendo de nuestras necesidades dentro del programa.
Sobrescribiendo el constructor
Existen momentos en los cuales debemos heredar desde las súper clases, para ello en ocasiones debemos sobrescribir el constructor veamos el siguiente ejemplo para poder entender de qué va todo esto:
Acá hemos creado una clase denominada Bird donde el constructor define el atributo hungry, ejecutamos los siguientes y vemos cómo funciona:
>>> b = Bird() >>> b.eat() Aaaah... >>> b.eat() No, thanks!
Ahora que sucede si heredamos de esta clase, veamos el siguiente código:
class SongBird(Bird): def __init__(self): self.sound = 'Squawk!' def sing(self): print self.sound
Corremos un pequeño programa:
>>> sb = SongBird() >>> sb.sing() Squawk!
Ahora si llamamos al método eat() veremos un error:
>>> sb.eat() Traceback (most recent call last): File "<stdin>", line 1, in ? File "birds.py", line 6, in eat if self.hungry: AttributeError: SongBird instance has no attribute 'hungry'
La excepción nos dice que no existe el atributo hungry por lo que debemos llamar al constructor de la super clase dentro de nuestro constructor:
class SongBird(Bird): def __init__(self): Bird.__init__(self) self.sound = 'Squawk!' def sing(self): print self.sound
Ahora al ejecutar el código todo andará sin problemas:
>>> sb = SongBird() >>> sb.sing() Squawk! >>> sb.eat() Aaaah... >>> sb.eat() No, thanks!
Con esto finalizamos el tutorial, ya conocemos como utilizar el método __init__ de forma básica y cómo hacerlo cuando debemos hacer herencia de una clase superior.