Come utilizzare i metodi __str__() e __repr__() in Python

Introduzione

In questo articolo, imparerai i metodi speciali __str__() e __repr__() definiti nel modello di dati di Python. I metodi __str__() e __repr__() possono essere utili nel debug del codice Python mediante il logging o la stampa di informazioni utili su un oggetto.

I metodi speciali di Python iniziano e terminano con un doppio trattino basso e sono informalmente conosciuti come metodi dunder. I metodi dunder sono i metodi sottostanti per gli operatori e le funzioni integrate di Python. Dovresti evitare di chiamare direttamente i metodi dunder e, invece, implementare i metodi dunder nella tua classe e poi utilizzare le funzioni integrate che li chiamano, come str() e repr().

Cosa differenzia __str__() da __repr__()?

Il metodo __str__() restituisce una rappresentazione della stringa di un oggetto leggibile dall’utente o informale. Questo metodo viene chiamato dalle funzioni incorporate print(), str() e format(). Se non si definisce un metodo __str__() per una classe, allora l’implementazione predefinita dell’oggetto incorporato richiama invece il metodo __repr__().

Il metodo __repr__() restituisce una rappresentazione della stringa di un oggetto più ricca di informazioni o ufficiale. Questo metodo viene chiamato dalla funzione incorporata repr(). Se possibile, la stringa restituita dovrebbe essere un’espressione Python valida che può essere utilizzata per ricreare l’oggetto. In tutti i casi, la stringa dovrebbe essere informativa e non ambigua.

In generale, la stringa __str__() è destinata agli utenti e la stringa __repr__() è destinata agli sviluppatori.

Esempi di __str__() e __repr__() utilizzando una classe incorporata

Gli esempi in questa sezione richiamano direttamente i metodi __str__() e __repr__() a scopo dimostrativo.

La classe datetime.datetime è una classe Python incorporata che ha un’implementazione predefinita dei metodi __str__() e __repr__().

Il codice di esempio seguente mostra le stringhe restituite dall’implementazione predefinita dei metodi __str__() e __repr__() per un oggetto datetime.datetime:

import datetime

mydate = datetime.datetime.now()

print("__str__() string: ", mydate.__str__())
print("str() string: ", str(mydate))

print("__repr__() string: ", mydate.__repr__())
print("repr() string: ", repr(mydate))

L’output è:

Output
__str__() string: 2023-01-27 09:50:37.429078 str() string: 2023-01-27 09:50:37.429078 __repr__() string: datetime.datetime(2023, 1, 27, 9, 50, 37, 429078) repr() string: datetime.datetime(2023, 1, 27, 9, 50, 37, 429078)

L’output mostra che la funzione str() chiama __str__() e restituisce una stringa amichevole per l’utente, mentre la funzione repr() chiama __repr__() e restituisce una stringa più ricca di informazioni che può essere utilizzata per ricreare l’oggetto. Infatti, è possibile utilizzare la funzione repr() con la funzione eval() per creare un nuovo oggetto dalla stringa:

import datetime

mydate1 = datetime.datetime.now()
mydate2 = eval(repr(mydate1))

print("mydate1 repr() string: ", repr(mydate1))
print("mydate2 repr() string: ", repr(mydate2))

print("the values of the objects are equal: ", mydate1==mydate2)

L’output è:

Output
mydate1 repr() string: datetime.datetime(2023, 1, 26, 9, 43, 24, 479635) mydate2 repr() string: datetime.datetime(2023, 1, 26, 9, 43, 24, 479635) the values of the objects are equal: True

Il codice di esempio precedente crea l’oggetto mydate2 dalla stringa repr() per mydate1, e quindi verifica che i valori di entrambi gli oggetti siano uguali.

Esempi di __str__() e __repr__() Utilizzando una Nuova Classe

Quando si crea una classe, si dovrebbe implementare almeno il metodo ___repr__() in modo che venga restituita un’informazione utile quando le funzioni integrate utilizzano __repr__().

La seguente classe non implementa i metodi __str__() o __repr()__:

class Ocean:

    def __init__(self, sea_creature_name, sea_creature_age):
        self.name = sea_creature_name
        self.age = sea_creature_age

c = Ocean('Jellyfish', 5)

print(str(c))
print(repr(c))

L’output quando si utilizza str() e repr() è:

Output
<__main__.Ocean object at 0x102892860> <__main__.Ocean object at 0x102892860>

L’esempio precedente dimostra che l’implementazione predefinita di __repr()__ per l’oggetto restituisce una stringa con solo la classe e l’id dell’oggetto nel formato esadecimale, il che non è molto utile. Nota che str() e repr() restituiscono lo stesso valore, perché str() chiama __repr__() quando __str__() non è implementato.

Aggiorna la classe Ocean con implementazioni dei metodi __str__() e __repr__():

class Ocean:

    def __init__(self, sea_creature_name, sea_creature_age):
        self.name = sea_creature_name
        self.age = sea_creature_age
    
    def __str__(self):
        return f'The creature type is {self.name} and the age is {self.age}'

    def __repr__(self):
        return f'Ocean(\'{self.name}\', {self.age})'

c = Ocean('Jellyfish', 5)

print(str(c))
print(repr(c))

Il risultato è:

Output
The creature type is Jellyfish and the age is 5 Ocean('Jellyfish', 5)

L’implementazione di __str__() nell’esempio precedente restituisce una stringa facile da leggere che fornisce i dettagli rilevanti dell’oggetto per un utente. L’implementazione di __repr__() restituisce una stringa che è un’espressione Python valida che potrebbe essere utilizzata per ricreare l’oggetto: Ocean('Medusa', 5). L’esempio utilizza il formato f-string per le stringhe, ma è possibile formattare le stringhe utilizzando qualsiasi formato supportato da Python.

Conclusione

In questo articolo, hai esplorato le differenze tra i metodi __str__() e __repr__() e hai implementato questi metodi speciali in una classe, in modo che non fosse necessario chiamarli direttamente. Per saperne di più sul lavoro con le stringhe in Python attraverso i nostri tutorial sulle stringhe in Python.

Source:
https://www.digitalocean.com/community/tutorials/python-str-repr-functions