94 votes

Quel est le but de __str__ et de __repr__ ?

Je ne comprends vraiment pas où sont les __str__ y __repr__ utilisé dans Python. Je veux dire que je comprends que __str__ renvoie la représentation sous forme de chaîne de caractères d'un objet. Mais pourquoi en aurais-je besoin ? Dans quel cas d'utilisation ? Par ailleurs, j'ai lu que l'utilisation de __repr__

Mais ce que je ne comprends pas, c'est où les utiliser ?

9 votes

5 votes

Pour ceux qui viennent de Ruby, le résumé est le suivant : __str__ = to_s y __repr__ = inspect .

3 votes

Cela répond-il à votre question ? Différence entre __str__ et __repr__ ?

91voto

miku Points 63392

__repr__

Appelé par le repr() et par des conversions de chaînes (guillemets inversés) pour calculer la représentation "officielle" d'un objet sous forme de chaîne de caractères. Dans la mesure du possible, cette représentation doit ressembler à une expression Python valide qui pourrait être utilisée pour recréer un objet avec la même valeur (dans un environnement approprié).

__str__

Appelé par le str() et par l'instruction print pour calculer la représentation "informelle" d'un objet sous forme de chaîne de caractères.

Utilice __str__ si vous avez une classe et que vous souhaitez obtenir une sortie informative/informelle lorsque vous utilisez cet objet dans une chaîne de caractères. Par exemple, vous pouvez définir __str__ pour les modèles Django, qui sont ensuite rendus dans l'interface d'administration de Django. Au lieu de quelque chose comme <Model object> vous obtiendrez par exemple le nom et le prénom d'une personne, le nom et la date d'un événement, etc.


__repr__ y __str__ sont similaires, voire parfois égaux (Exemple de BaseSet dans la classe sets.py de la bibliothèque standard) :

def __repr__(self):
    """Return string representation of a set.

    This looks like 'Set([<list of elements>])'.
    """
    return self._repr()

# __str__ is the same as __repr__
__str__ = __repr__

70voto

Scott Griffiths Points 8867

Le seul endroit où l'on utilise souvent les deux, c'est lors d'une session interactive. Si vous imprimez un objet, son __str__ sera appelée, alors que si vous utilisez un objet seul, sa méthode __repr__ est affichée :

>>> from decimal import Decimal
>>> a = Decimal(1.25)
>>> print(a)
1.25                  <---- this is from __str__
>>> a
Decimal('1.25')       <---- this is from __repr__

Les __str__ est destiné à être aussi lisible que possible par l'homme, alors que le __repr__ doit permettre de recréer l'objet, même si ce n'est pas toujours la façon dont il a été créé, comme c'est le cas ici.

Il n'est pas rare non plus que les deux __str__ y __repr__ pour renvoyer la même valeur (en tout cas pour les types intégrés).

19voto

user1767754 Points 460

Renforcer les réponses précédentes et montrer d'autres exemples. Si elle est utilisée correctement, la différence entre str y repr est claire. En bref repr doit renvoyer une chaîne de caractères qui peut être copiée-collée pour reconstruire l'état exact de l'objet, alors que str est utile pour logging y observing les résultats du débogage. Voici quelques exemples de résultats différents pour des bibliothèques connues.

Date

print repr(datetime.now())    #datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)
print str(datetime.now())     #2017-12-12 18:49:27.134452

Les str est bon pour l'impression dans un fichier journal, alors que repr peut être réutilisé si vous souhaitez l'exécuter directement ou le transférer sous forme de commandes dans un fichier.

x = datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)

Numpy

print repr(np.array([1,2,3,4,5])) #array([1, 2, 3, 4, 5])
print str(np.array([1,2,3,4,5]))  #[1 2 3 4 5]

dans Numpy, le repr est à nouveau directement consommable.

Exemple de Vector3 personnalisé

class Vector3(object):
    def __init__(self, args):
        self.x = args[0]
        self.y = args[1]
        self.z = args[2]

    def __str__(self):
        return "x: {0}, y: {1}, z: {2}".format(self.x, self.y, self.z)

    def __repr__(self):
        return "Vector3([{0},{1},{2}])".format(self.x, self.y, self.z)

Dans cet exemple, repr renvoie à nouveau une chaîne de caractères qui peut être directement consommée/exécutée, alors que str est plus utile comme sortie de débogage.

v = Vector3([1,2,3])
print str(v)     #x: 1, y: 2, z: 3
print repr(v)    #Vector3([1,2,3])

Une chose à garder à l'esprit, si str n'est pas défini mais repr , str appellera automatiquement repr . Il est donc toujours bon de définir au moins ce qui suit repr

17voto

Peter Rowell Points 12444

Sauterelle, en cas de doute aller à la montagne y lire les textes anciens . Vous y trouverez que __repr__() doit :

Dans la mesure du possible, cela doit ressembler à une expression Python valide qui pourrait être utilisée pour recréer un objet avec la même valeur.

7 votes

-1 car cela ne tente même pas de répondre à la question réelle, à savoir quels sont les cas d'utilisation.

4 votes

@Scott : Vous avez raison. Mais encore une fois, le question réelle a montré qu'il n'avait absolument pas essayé d'aller voir les médecins de premier recours en premier lieu. C'est une chose de poser une question qui montre que vous avez essayé d'y répondre par vous-même mais que vous êtes encore un peu confus sur certains aspects, et c'en est une autre de poster une question comme celle-ci. Il suffit de taper l'objet de sa question comme s'il s'agissait d'une nouvelle question pour constater que 5 des 6 premiers fils de discussion suggérés auraient répondu à sa question, mais qu'il ne s'est pas donné la peine de s'en préoccuper. Je ne lui ai pas donné une réponse complète, mais j'ai été très tenté de le faire.

1 votes

En fait, il a dit qu'il avait lu à propos de __repr__ Si vous pensez que la question ne vaut pas la peine d'être traitée, vous pouvez simplement ne pas y répondre, bien que dans ce cas, je suis d'accord pour dire qu'elle est déjà très bien traitée sur SO et qu'un lien vers les doublons serait une réponse appropriée.

7voto

Zorana Points 61

Organisons une classe sans __str__ fonction.

class Employee:

    def __init__(self, first, last, pay):
        self.first = first 
        self.last = last
        self.pay = pay

emp1 = Employee('Ivan', 'Smith', 90000)

print(emp1)

Lorsque nous imprimons cette instance de la classe, emp1 Voilà ce que nous obtenons :

<__main__.Employee object at 0x7ff6fc0a0e48>

Ce n'est pas très utile, et ce n'est certainement pas ce que nous voulons imprimer si nous l'utilisons pour afficher (comme en html)

Maintenant, la même classe, mais avec __str__ fonction :

class Employee:

    def __init__(self, first, last, pay):
        self.first = first 
        self.last = last
        self.pay = pay

    def __str__(self):
        return(f"The employee {self.first} {self.last} earns {self.pay}.")
        # you can edit this and use any attributes of the class

emp2 = Employee('John', 'Williams', 90000)

print(emp2)

Maintenant, au lieu d'imprimer qu'il y a un objet, nous obtenons ce que nous avons spécifié avec le retour de __str__ fonction :

The employee John Williams earns 90000

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X