Python >> Tutoriel Python >  >> Python

__str__ contre __repr__ en Python

Résumé : L'objectif clé de __str__ et __repr__ est de retourner une représentation sous forme de chaîne d'un objet Python. La façon dont ils représentent l'objet string les différencie.

  • str()__str()__ renvoyer un imprimable /lisible représentation sous forme de chaîne d'un objet centré sur l'utilisateur final.
  • repr()__repr()__ renvoie une représentation sous forme de chaîne d'un objet qui est un objet Python valide , quelque chose que vous pouvez transmettre à eval() ou tapez dans le shell Python sans obtenir d'erreur. Son objectif principal est d'être sans ambiguïté .

Énoncé du problème : Quelle est la différence entre __str__ et __repr__ en Python ?

Tout d'abord, voyons pourquoi il s'agit de l'une des questions les plus fréquemment posées sur Internet. Examinons un exemple pour comprendre la raison de la confusion.

Exemple 1 :

name = 'FINXTER'
print(str(name))
print(repr(name))

Sortie :

FINXTER
'FINXTER'

Maintenant, vous voyez pourquoi c'est si déroutant ! ? Les deux semblent imprimer la chaîne FINXTER . Ainsi, les deux sont des fonctions intégrées et renvoient toutes deux une représentation sous forme de chaîne d'un objet; La seule différence visible dans ce cas est - str() imprime la chaîne sans les guillemets (FINXTER ), tandis que repr() l'imprime avec les guillemets ('FINXTER' ).

Remarque :Au cas où vous vous demanderiez pourquoi utilisons-nous repr() et str() au lieu de __repr__ et __str__ alors s'il vous plaît jeter un oeil à la note ci-dessous :

  • __repr__
    • Appelé par le repr() fonction intégrée
  • __str__
    • Appelé par le str() fonction intégrée

Mais maintenant, regardons un exemple différent ;

Exemple 2 :

from datetime import datetime

d = datetime.now()
print(str(d))
print(repr(d))

Sortie :

2020-11-04 16:38:20.048483
datetime.datetime(2020, 11, 4, 16, 38, 20, 48483)

Dans le deuxième exemple, nous pouvons clairement visualiser la différence entre repr() et str() .

Jetons un coup d'œil à ce que dit la documentation officielle à propos de object.__repr__(self) et object.__str__(self) :

En d'autres termes, nous pouvons dire que :

❖ Le but de __repr__ est d'être sans ambiguïté

Le __repr__() renvoie la représentation objet de toute expression python valide telle que tuple, dictionnaire, chaîne, etc. Cela signifie que chaque fois que le repr() est invoquée sur l'objet, elle renverra l'objet lui-même et pourra donc être évaluée avec le eval() fonction de recréer l'objet lui-même en raison de sa nature non ambiguë. Ainsi, repr(25)!=repr("25") .

Jetons un coup d'œil à un exemple rapide où nous pouvons utiliser repr() sur une expression et l'évaluer à l'aide de eval() fonction.

Remarque : Vous ne pouvez pas utiliser le eval() fonction sur str() qui est clairement illustré dans l'exemple ci-dessous.

Exemple :

text1 = 'a string'
text2 = eval(repr(text1))
if text1 == text2:
  print("eval() Works!")
text3 = eval(str(text1))
if text1 == text3:
  print("eval() Works!")

Sortie :

eval() Works!
Traceback (most recent call last):
  File "main.py", line 5, in <module>
    text3 = eval(str(text1))
  File "<string>", line 1
    a string
      ^
SyntaxError: unexpected EOF while parsing

❖ Le but de __str__ est d'être lisible

L'objectif de __str__ n'est pas sans ambiguïté, son but est plutôt de fournir une représentation qu'un utilisateur est plus lisible à l'utilisateur. Ainsi, str(25)==str("25") .

Examinons un exemple très simple qui démontre la nature non ambiguë de repr() et l'aspect lisibilité de str() .

if str(25)==str("25"):
  print("Goal of __str__ : Readability")
if repr(25)!=repr("25"):
  print("Goal of __repr__ : Unamgiuity")

Sortie :

Goal of __str__ : Readability
Goal of __repr__ : Unamgiuity

En termes simples, __repr__ est pour les développeurs tandis que __str__ est pour les clients!

Points à retenir

❖ Pour les conteneurs, __str__ utilise le __repr__ des objets contenus

Pour simplifier les choses prenons l'aide d'un exemple :

rank = {'Rick': 1}
language = ['Python', 'Java']
error = (404, 'status_code')
for item in (rank, language, error):
  print(f"{str(type(item)):}")
  print(f"repr() representation: {repr(item):}")
  print(f"str() representation: {str(item)}")
  print("\n")

Sortie :

<class 'dict'>
repr() representation: {'Rick': 1}
str() representation: {'Rick': 1}


<class 'list'>
repr() representation: ['Python', 'Java']
str() representation: ['Python', 'Java']


<class 'tuple'>
repr() representation: (404, 'status_code')
str() representation: (404, 'status_code')

Dans l'exemple ci-dessus, il est clair que même lorsque nous utilisons le str() sur un objet conteneur, la fonction str() invoque leur __repr()__ méthode; par conséquent, nous obtenons l'objet lui-même en sortie et il n'y a pas de différence entre str() et repr() lorsqu'il est utilisé avec des objets. Cela justifie que pour les conteneurs __str__ utilise le __repr__ des objets contenus .

❖ L'implémentation par défaut de __str__ et __repr__ est inutile

L'implémentation par défaut de __str__ et __repr__ est inutile et à moins que vous ne vous assuriez de les définir et de les utiliser spécifiquement, la plupart des classes n'ont pas de résultats utiles pour l'un ou l'autre. Mettons les choses au clair à l'aide d'un autre exemple :

class Finxter(object):
  pass 
print(str(Finxter()))
print(repr(Finxter()))

Sortie :

<__main__.Finxter object at 0x7f85641d15e0>
<__main__.Finxter object at 0x7f85641d15e0>

Comme vu ci-dessus, il n'y a aucune différence entre les deux méthodes et aucune information au-delà des classes id .

Remarque : Un objet se comportera comme si __str__=__repr__ si __repr__ est défini, et __str__ n'est pas.

Essayons maintenant de remplacer le __str__ et __repr__ méthodes pour visualiser leur comportement sur Objets personnalisés. Veuillez suivre l'exemple ci-dessous.

Exemple :

class Finxter(object):
  def __str__(object):
     return str("Freelancing")
  
  def __repr__(object):
     return repr("Freelancing")

print(str(Finxter()))
print(repr(Finxter()))
print(eval(repr(Finxter())))

Sortie :

Freelancing
'Freelancing'
Freelancing

D'après l'exemple ci-dessus, il est clair que __repr__() cab être facilement remplacé afin que repr() fonctionne différemment.

Remarque : Si vous remplacez __repr__ , qui sera également utilisé pour  __str__ , mais l'inverse n'est pas possible. Voyons cela dans l'exemple ci-dessous.

Exemple A : Remplacer __repr__ remplace également __str__

class Finxter(object):
  def __repr__(object):
     return repr("Freelancing")

print(str(Finxter()))
print(repr(Finxter()))

Sortie :

'Freelancing'
'Freelancing'

Exemple B : Remplacer __str__ n'affecte pas __repr__

class Finxter(object):
  def __str__(object):
     return str("Freelancing")

print(str(Finxter()))
print(repr(Finxter()))

Sortie :

Freelancing
<__main__.Finxter object at 0x7f3b284ef5e0>

Conclusion

Résumons la principale différence entre __repr__ et __str__

str() repr()
C'est le non officiel représentation sous forme de chaîne et utilisée pour rendre l'objet lisible . C'est le officiel représentation sous forme de chaîne et utilisée pour rendre l'objet sans ambiguïté .
Génère une sortie destinée aux utilisateurs finaux . Génère une sortie utile pour les développeurs .

Veuillez vous abonner et rester à l'écoute pour d'autres articles intéressants !