49 - Método especial __str__

Podemos hacer que se ejecute un método definido por nosotros cuando pasamos un objeto a la función print o cuando llamamos a la función str (convertir a string)

¿Qué sucede cuando llamamos a la función print y le pasamos como parámetro un objeto?

Ver video

class Persona:
    def __init__(self,nom,ape):
        self.nombre=nom
        self.apellido=ape
 
persona1=Persona("Jose","Rodriguez")
print(persona1)

Nos muestra algo parecido a esto:

<__main__.Persona object at 0x03E99C90>

Python nos permite redefinir el método que se debe ejecutar. Esto se hace definiendo en la clase el método especial __str__

En el ejemplo anterior si queremos que se muestre el nombre y apellido separados por coma cuando llamemos a la función print el código que debemos implementar es el siguiente:

class Persona:
    def __init__(self,nom,ape):
        self.nombre=nom
        self.apellido=ape

    def __str__(self):
        cadena=self.nombre+","+self.apellido
        return cadena
 
persona1=Persona("Jose","Rodriguez")
print(persona1)

Como vemos debemos implementar el método __str__ y retornar un string, este luego será el que imprime la función print:

    def __str__(self):
        cadena=self.nombre+","+self.apellido
        return cadena

Esta característica definida en Python nos permite crear programas muy legibles y flexibles.

El método __str__ también se ejecuta si llamamos a la función str y pasamos como parámetro un objeto que tiene definido dicho método:

class Persona:
    def __init__(self,nom,ape):
        self.nombre=nom
        self.apellido=ape

    def __str__(self):
        cadena=self.nombre+","+self.apellido
        return cadena


# bloque principal
 
persona1=Persona("Jose","Rodriguez")
persona2=Persona("Ana","Martinez")
print(str(persona1)+"-"+str(persona2))  # Jose,Rodriguez-Ana,Martinez 

Problema 1:

Definir una clase llamada Punto con dos atributos x e y.
Crearle el método especial __str__ para retornar un string con el formato (x,y).

Programa: ejercicio205.py

Ver video

class Punto:

    def __init__(self, x, y):
        self.x=x
        self.y=y

    def __str__(self):
        return "("+str(self.x)+","+str(self.y)+")"


# bloque principal

punto1=Punto(10,3)
punto2=Punto(3,4)
print(punto1)
print(punto2)

La clase Punto define dos métodos especiales. El método __init__ donde inicializamos los atributos x e y:

class Punto:

    def __init__(self, x, y):
        self.x=x
        self.y=y

Y el segundo método especial que definimos es el __str__ que debe retornar un string. Para generar el string debemos concatenar valores fijos como "(" y convertir a string los atributos que son enteros mediante la función str:

    def __str__(self):
        return "("+str(self.x)+","+str(self.y)+")"

Luego en el bloque principal después de definir dos objetos de la clase Punto procedemos a llamar a la función print y le pasamos cada uno de los objetos:

# bloque principal

punto1=Punto(10,3)
punto2=Punto(3,4)
print(punto1)
print(punto2)

Hay que tener en cuenta que cuando pasamos a la función print el objeto punto1 en ese momento se llama el método especial __str__ que tiene por objetivo retornar un string que nos haga más legible lo que representa dicho objeto.

Problema 2:

Declarar una clase llamada Familia. Definir como atributos el nombre del padre, madre y una lista con los nombres de los hijos.
Definir el método especial __str__ que retorne un string con el nombre del padre, la madre y de todos sus hijos.

Programa: ejercicio206.py

Ver video

class Familia:

    def __init__(self,padre,madre,hijos=[]):
        self.padre=padre
        self.madre=madre
        self.hijos=hijos

    def __str__(self):
        cadena=self.padre+","+self.madre
        for hi in self.hijos:
            cadena=cadena+","+hi
        return cadena


# bloque principal

familia1=Familia("Pablo","Ana",["Pepe","Julio"])
familia2=Familia("Jorge","Carla")
familia3=Familia("Luis","Maria",["marcos"])

print(familia1)
print(familia2)
print(familia3)

Para resolver este problema el método __init__ recibe en forma obligatoria el nombre del padre, madre y en forma opcional una lista con los nombres de los hijos:

class Familia:

    def __init__(self,padre,madre,hijos=[]):
        self.padre=padre
        self.madre=madre
        self.hijos=hijos

Si no tiene hijos la familia el atributo hijos almacena una lista vacía.

El método especial __str__ genera un string con los nombres del padre, madre y todos los hijos:

    def __str__(self):
        cadena=self.padre+","+self.madre
        for hi in self.hijos:
            cadena=cadena+","+hi
        return cadena

En el bloque principal creamos tres objetos de la clase Familia y pasamos al método __init__ distintas composiciones de familias:

# bloque principal

familia1=Familia("Pablo","Ana",["Pepe","Julio"])
familia2=Familia("Jorge","Carla")
familia3=Familia("Luis","Maria",["marcos"])

print(familia1)
print(familia2)
print(familia3)

metodo __str__ en Python

Problema propuesto

  • Desarrollar un programa que implemente una clase llamada Jugador.
    Definir como atributos su nombre y puntaje.
    Codificar el método especial __str__ que retorne el nombre y si es principiante (menos de 1000 puntos) o experto (1000 o más puntos)

    Ver video

Solución
ejercicio207.py

class Jugador:

    def __init__(self, nombre, puntaje):
        self.nombre=nombre
        self.puntaje=puntaje

    def __str__(self):
        cadena=self.nombre+"-"
        if self.puntaje<1000:
            cadena=cadena+"principiante"
        else:
            cadena=cadena+"experto"
        return cadena


# bloque principal

jugador1=Jugador("Juan",750)
jugador2=Jugador("Ana",1200)
print(jugador1)
print(jugador2)