Was ist der Unterschied zwischen __str__
y __repr__
in Python?
Sie befindet sich auf pg. #351.
Auf Seite 358 des Buches Python-Skripte für die Computerwissenschaft von Hans Petter Langtangen, heißt es eindeutig, dass
__repr__
zielt auf eine vollständige String-Darstellung des Objekts ab;__str__
ist es, eine schöne Zeichenkette zum Ausdrucken zurückzugeben.Ich ziehe es also vor, sie zu verstehen als
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:
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'
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 ...
.
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)
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. "
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.
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.
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 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.