str vs repr en Python: explicado
Published 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.
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.
-
¿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. -
¿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__
. -
¿
__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 utilizandoeval()
.