3676 Stimmen

Was ist der Unterschied zwischen __str__ und __repr__?

Was ist der Unterschied zwischen __str__ y __repr__ in Python?

49voto

Yong Yang Punkte 1090

Auf Seite 358 des Buches Python-Skripte für die Computerwissenschaft von Hans Petter Langtangen, heißt es eindeutig, dass

  • Le site __repr__ zielt auf eine vollständige String-Darstellung des Objekts ab;
  • Le site __str__ ist es, eine schöne Zeichenkette zum Ausdrucken zurückzugeben.

Ich ziehe es also vor, sie zu verstehen als

  • repr = vervielfältigen
  • str = string (Darstellung)

vom Standpunkt des Benutzers aus gesehen obwohl dies ein Missverständnis ist, das ich beim Lernen von Python gemacht habe.

Ein kleines, aber gutes Beispiel wird auf derselben Seite wie folgt angeführt:

Beispiel

In [38]: str('s')
Out[38]: 's'

In [39]: repr('s')
Out[39]: "'s'"

In [40]: eval(str('s'))
Traceback (most recent call last):

  File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
    eval(str('s'))

  File "<string>", line 1, in <module>

NameError: name 's' is not defined

In [41]: eval(repr('s'))
Out[41]: 's'

0 Stimmen

Sie befindet sich auf pg. #351.

10 Stimmen

Es ist etwas irreführend, sich auf repr zu reproduzieren. Es ist besser, es als "repräsentieren" zu bezeichnen.

48voto

Abgesehen von all den gegebenen Antworten möchte ich noch einige Punkte hinzufügen :-

1) __repr__() wird aufgerufen, wenn Sie einfach den Namen des Objekts in die interaktive Python-Konsole schreiben und die Eingabetaste drücken.

2) __str__() wird aufgerufen, wenn Sie das Objekt mit der Anweisung print verwenden.

3) Für den Fall, dass __str__ fehlt, dann drucken und jede Funktion, die str() ruft auf. __repr__() des Objekts.

4) __str__() von Containern, wenn sie aufgerufen werden, ausführen __repr__() Methode der darin enthaltenen Elemente.

5) str() aufgerufen innerhalb __str__() könnte möglicherweise ohne Basisfall rekursieren und bei der maximalen Rekursionstiefe einen Fehler machen.

6) __repr__() anrufen können repr() das automatisch versucht, eine unendliche Rekursion zu vermeiden, indem es ein bereits dargestelltes Objekt durch ... .

17voto

Zer0 Punkte 942

Um es einfach auszudrücken:

__str__ wird verwendet, um eine String-Darstellung Ihres Objekts anzuzeigen leicht zu lesen von anderen.

__repr__ wird verwendet, um eine String-Darstellung von die Objekt.

Nehmen wir an, ich möchte eine Fraction Klasse, wobei die String-Darstellung eines Bruchs '(1/2)' ist und das Objekt (Klasse Fraction) als 'Fraction (1,2)' dargestellt werden soll

Wir können also eine einfache Fraction-Klasse erstellen:

class Fraction:
    def __init__(self, num, den):
        self.__num = num
        self.__den = den

    def __str__(self):
        return '(' + str(self.__num) + '/' + str(self.__den) + ')'

    def __repr__(self):
        return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'

f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)

15voto

Casebash Punkte 106938

Desde ein (inoffizielles) Python-Referenz-Wiki (Archivkopie) von effbot:

__str__ " berechnet die "informelle" String-Darstellung eines Objekts. Dies unterscheidet sich von __repr__ dass es sich nicht um einen gültigen Python-Ausdruck handeln muss: Stattdessen kann eine bequemere oder prägnantere Darstellung verwendet werden. "

4 Stimmen

__repr__ muss auf keinen Fall einen gültigen Python-Ausdruck zurückgeben.

14voto

asmeurer Punkte 79555

Um ganz ehrlich zu sein, eval(repr(obj)) wird nie verwendet. Wenn Sie es dennoch verwenden, sollten Sie damit aufhören, denn eval ist gefährlich, und Strings sind ein sehr ineffizienter Weg, um Ihre Objekte zu serialisieren (verwenden Sie pickle stattdessen).

Daher würde ich empfehlen, Folgendes einzustellen __repr__ = __str__ . Der Grund dafür ist, dass str(list) ruft auf. repr auf die Elemente (ich halte dies für einen der größten Designfehler von Python, der in Python 3 nicht behoben wurde). Eine aktuelle repr wird wahrscheinlich nicht sehr hilfreich sein, da die Ausgabe von print([your, objects]) .

Meiner Erfahrung nach ist der nützlichste Anwendungsfall der repr Funktion ist es, eine Zeichenkette in eine andere Zeichenkette einzufügen (unter Verwendung der Zeichenkettenformatierung). Auf diese Weise müssen Sie sich keine Gedanken über Anführungszeichen oder ähnliches machen. Beachten Sie aber, dass es keine eval passiert hier.

26 Stimmen

Ich glaube, das geht an der Sache vorbei. Die Verwendung von eval(repr(obj)) ist ein Sicherheitstest und eine Faustregel - wenn das ursprüngliche Objekt damit korrekt wiederhergestellt wird, haben Sie eine annehmbare __repr__ Umsetzung. Es ist nicht beabsichtigt, dass Sie Objekte tatsächlich auf diese Weise serialisieren.

10 Stimmen

eval ist nicht von Natur aus gefährlich. Ist nicht gefährlicher als unlink , open oder das Schreiben in Dateien. Sollten wir aufhören, in Dateien zu schreiben, weil ein bösartiger Angriff vielleicht einen beliebigen Dateipfad verwenden könnte, um darin Inhalte zu speichern? Alles ist gefährlich, wenn es dummerweise von dummen Menschen benutzt wird. Dummheit ist gefährlich. Dunning-Kruger-Effekte sind gefährlich. eval ist nur eine Funktion.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X