Skip to content

str vs repr en Python: explicado

Updated on

En el ámbito de la programación Python, __str__ y __repr__ son métodos dunders (doble guion bajo), también conocidos como métodos mágicos o métodos especiales. Sirven como la base de la programación orientada a objetos en Python. Esta guía comprehensiva busca iluminar las funcionalidades distintivas de estos dos métodos, su importancia en Python y las instancias adecuadas para su aplicación. Además, esta guía presentará numerosos ejemplos de código para afianzar los conceptos subyacentes.

¿Quieres crear rápidamente visualizaciones de datos desde un DataFrame de Pandas en Python sin código?

PyGWalker es una librería de Python para el Análisis Exploratorio de Datos con Visualización. PyGWalker (opens in a new tab) puede simplificar tu flujo de trabajo de análisis y visualización de datos en cuadernos de Jupyter, convirtiendo tu DataFrame de pandas (y DataFrame de polars) en una interfaz de usuario de estilo Tableau para exploración visual.

PyGWalker para visualización de datos (opens in a new tab)

Definición de los Términos: __str__ vs __repr__

Antes de adentrarnos en lo profundo, comencemos definiendo estos dos métodos importantes:

Método __str__

En Python, __str__ es el método utilizado para calcular la representación en cadena "informal" o fácilmente imprimible de un objeto. Está diseñado para proporcionar una salida legible para los humanos. Por lo tanto, la legibilidad es una consideración clave al implementar este método.

Aquí tienes un ejemplo simple:

class Persona:
    def __init__(self, nombre, edad):
        self.nombre = nombre
        self.edad = edad
 
    def __str__(self):
        return f'{self.nombre} tiene {self.edad} años.'
 
john = Persona('John Doe', 30)
print(str(john))  # Salida: John Doe tiene 30 años.

Método __repr__

Por otro lado, __repr__ es un método utilizado para calcular la representación en cadena "oficial" de un objeto. Su finalidad es proporcionar una representación detallada que se pueda utilizar para recrear el objeto si se le pasa a la función eval(). Es particularmente útil para la depuración y el registro, ya que proporciona una descripción completa del objeto.

Considera la misma clase Persona, pero con un método __repr__:

class Persona:
    def __init__(self, nombre, edad):
        self.nombre = nombre
        self.edad = edad
 
    def __repr__(self):
        return f'Persona(nombre={self.nombre}, edad={self.edad})'
 
john = Persona('John Doe', 30)
print(repr(john))  # Salida: Persona(nombre=John Doe, edad=30)

La salida del método __repr__ es mucho más detallada y técnica en comparación con el método __str__. Este nivel de detalle es exactamente lo que un desarrollador necesita para una depuración o registro eficaz.

Cuándo usar __str__ vs __repr__

Ahora que tenemos una comprensión básica de estos métodos, exploremos cuándo utilizar cada uno.

Implementando __str__ para una Representación en Cadena Amigable para el Usuario

El método __str__ se utiliza principalmente para los usuarios finales. Proporciona una descripción informal y más legible de un objeto. Puedes pensar en él como una forma de mostrar objetos de una manera que tenga sentido para los usuarios que no necesariamente son programadores.

Al implementar este método en tus clases de Python, concéntrate en proporcionar información que sea relevante y beneficiosa para el usuario final.

class Producto:
    def __init__(self, nombre, precio):
        self.nombre = nombre
        self.precio = precio
 
    def __str__(self):
        return f'{self.nombre} cuesta ${self.precio}.'
 
iPhone = Producto('iPhone', 999)
print(str(iPhone))  # Salida: iPhone cuesta $999.

En el ejemplo anterior, el método __str__ proporciona una descripción simple y legible para el humano del objeto Producto. La salida de str(iPhone) se podría mostrar directamente a los usuarios en un sitio web o en una aplicación.

Implementando __repr__ para Depuración y Desarrollo

El método __repr__, por otro lado, está destinado principalmente a los desarrolladores. Proporciona una representación completa e inequívoca del objeto, que puede ser muy útil para la depuración y el registro.

Una regla de oro al implementar el método __repr__ es que, si es posible, debe devolver una cadena que permita recrear el objeto utilizando la función eval(). Esto no siempre es posible, especialmente para objetos complejos, pero es una buena pauta a seguir.

Considera la clase Producto con un método __repr__:

class Producto:
    def __init__(self, nombre, precio):
        self.nombre = nombre
        self.precio = precio
 
    def __repr__(self):
        return f'Producto(nombre={self.nombre}, precio={self.precio})'
 
iPhone = Producto('iPhone', 999)
print(repr(iPhone))  # Salida: Producto(nombre=iPhone, precio=999)

La salida del método __repr__ es mucho más detallada y técnica en comparación con el método __str__. Este nivel de detalle es exactamente lo que un desarrollador necesita para una depuración o registro eficaz.

Adaptando __str__ y __repr__ para tus Clases de Python

Ahora que comprendes los casos de uso principales para ambos métodos, hablemos sobre cómo adaptarlos a tus necesidades. En muchos casos, querrás definir ambos métodos en tus clases, pero su implementación dependerá en gran medida de tu caso de uso específico.

Estableciendo __str__ para una Representación Personalizada en Forma de Cadena

Cuando definas el método __str__, piensa en las personas que interactuarán con tu objeto y en lo que necesitan saber. El método debe devolver una cadena que proporcione un resumen conciso y legible para los humanos del objeto.

Supongamos que tenemos una clase Pelicula en una aplicación de reserva de entradas de cine:

class Pelicula:
    def __init__(self, titulo, director, calificacion):
        self.titulo = titulo
        self.director = director
        self.calificacion = calificacion
def __str__(self):
    return f'{self.title} de {self.director}, valorada {self.rating}/10.'
 
inception = Movie('Inception', 'Christopher Nolan', 8.8)
print(str(inception))  # Resultado: Inception de Christopher Nolan, valorada 8.8/10.
 
### Definición de `__repr__` para una descripción detallada del objeto
 
Al implementar el método `__repr__`, considera qué sería útil para alguien que depure el código o registre el estado de un objeto. El string debe incluir toda la información necesaria para comprender el objeto de un vistazo.
 
Continuando con la clase `Movie`, un método `__repr__` podría verse así:
 
```python
class Movie:
    def __init__(self, title, director, rating):
        self.title = title
        self.director = director
        self.rating = rating
 
    def __repr__(self):
        return f'Película(título={self.title}, director={self.director}, valoración={self.rating})'
 
inception = Movie('Inception', 'Christopher Nolan', 8.8)
print(repr(inception))  # Resultado: Película(título=Inception, director=Christopher Nolan, valoración=8.8)

Preguntas frecuentes: Entendiendo los métodos __str__ y __repr__ de Python

Ahora hemos explorado los conceptos básicos de los métodos __str__ y __repr__ de Python. Sin embargo, es posible que aún tengas preguntas sobre estos métodos de doble guion bajo. A continuación, abordaremos algunas preguntas frecuentes.

  1. ¿Qué sucede si no defino __str__ y __repr__ en mi clase de Python?

    Si no defines __str__ o __repr__ en tu clase, Python utiliza sus implementaciones predeterminadas. El método predeterminado __str__ devuelve un string que contiene el nombre de la clase y su dirección en memoria, mientras que __repr__ hace lo mismo.

  2. ¿Debería siempre implementar ambos métodos __str__ y __repr__ en mis clases?

    Es una buena práctica implementar al menos __repr__, ya que se utiliza como alternativa si __str__ no está definido. Sin embargo, implementar ambos depende de tus necesidades específicas. Si los objetos de tu clase necesitan tener una representación de string amigable para el usuario, entonces vale la pena implementar también __str__.

  3. ¿__str__ y __repr__ pueden devolver cualquier tipo de string?

    Si bien técnicamente __str__ y __repr__ pueden devolver cualquier string, es mejor seguir las convenciones: __str__ debe ser legible y conciso, mientras que __repr__ debe ser detallado y, si es posible, permitir que el objeto se reproduzca utilizando eval().