Unterschied zwischen __str__ und __repr__?
Was ist der Unterschied zwischen __str__
und __repr__
im Python
?
InformationsquelleAutor der Frage Casebash | 2009-09-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was ist der Unterschied zwischen __str__
und __repr__
im Python
?
InformationsquelleAutor der Frage Casebash | 2009-09-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Alex gut zusammengefasst, aber erstaunlicherweise war zu lapidar.
Erste, lassen Sie mich noch einmal die wichtigsten Punkte in Alex ' s post:
__repr__
Ziel ist eindeutig__str__
Ziel ist lesbar__str__
verwendet die enthaltenen Objekte'__repr__
Default-Implementierung ist die nutzlos
Dies ist vor allem eine überraschung, weil Python die Standardeinstellungen sind in der Regel Recht nützlich. In diesem Fall jedoch, dass ein Standard für
__repr__
würde handeln wie:zu gefährlich gewesen wäre (zum Beispiel, zu leicht in eine unendliche Rekursion, wenn Objekte sich gegenseitig referenzieren). Also Python-cops aus. Beachten Sie, dass es ist ein Standard, das ist wahr: wenn
__repr__
definiert ist, und__str__
ist nicht, das Objekt verhält sich, als ob__str__=__repr__
.Dies bedeutet, in einfachen Worten: fast jedes Objekt, das Sie implementieren sollten, haben Sie eine funktionale
__repr__
das ist brauchbar für das Verständnis der Objekt. Die Umsetzung__str__
ist optional: das tun Sie, wenn Sie ein "pretty print" - Funktionalität (zum Beispiel, von einem report-generator).Das Ziel
__repr__
ist eindeutig seinLassen Sie mich kommen direkt aus und sagen, es — ich glaube nicht im Debugger. Ich weiß wirklich nicht, wie zu verwenden debugger, und noch nie einer ernst. Außerdem glaube ich, dass die großen Fehler im Debugger ist Ihre grundlegende Natur — die meisten Ausfälle, die ich Debuggen geschah vor langer, langer Zeit, in einer Galaxie weit, weit entfernt. Dies bedeutet, dass ich glaube, mit religiöser Inbrunst, in der Protokollierung. Die Protokollierung ist das Lebenselixier jeder anständige Feuer-und-vergessen-server-system. Python macht es einfach zu melden: mit vielleicht einige Projekt-spezifischen wrappers, alles, was Sie brauchen, ist ein
Aber Sie haben zu tun ist der Letzte Schritt — stellen Sie sicher, dass jedes Objekt, das Sie implementieren, hat eine nützliche repr, so code wie, dass kann nur funktionieren. Dies ist der Grund, warum die "eval" - Sache kommt: wenn Sie genügend Informationen haben, so
eval(repr(c))==c
das heißt, Sie wissen alles, was es zu wissen gibt überc
. Wenn es das ist, einfach genug, zumindest eine ungenaue Art und Weise, es zu tun. Wenn nicht, stellen Sie sicher, Sie haben genug Informationen überc
sowieso. Normalerweise verwende ich ein eval-format:"MyClass(this=%r,that=%r)" % (self.this,self.that)
. Es bedeutet nicht, dass Sie tatsächlich bauen MyClass, oder, dass diejenigen, die richtigen Argumente im Konstruktor — aber es ist eine nützliche form, um auszudrücken, "das ist alles, was Sie wissen müssen über diese Instanz".Hinweis: ich habe
%r
oben, nicht%s
. Sie wollen immer zu verwendenrepr()
[oder%r
Formatierung-Zeichen, was dasselbe ist] in__repr__
Umsetzung, oder Sie sind zu besiegen, das Ziel der repr. Sie wollen in der Lage sein, zu differenzierenMyClass(3)
undMyClass("3")
.Das Ziel
__str__
ist lesbarSpeziell, es soll nicht eindeutig sein — beachten Sie, dass
str(3)==str("3")
. Ebenso, wenn Sie bei der Implementierung eines IP-Abstraktion, mit der str es Aussehen 192.168.1.1 ist auch gut so. Bei der Implementierung eines Datum - /Zeit-Abstraktion, die str werden kann "2010/4/12 15:35:22", etc. Das Ziel ist es, stellen es in einer Weise, dass ein Benutzer, kein Programmierer, würde es Lesen wollen. Abhacken nutzlos Ziffern, so tun, als einige andere in der Klasse ist, wie lange es unterstützt die Lesbarkeit, es ist eine Verbesserung.Container
__str__
verwendet die enthaltenen Objekte'__repr__
Dies scheint überraschend, nicht wahr? Es ist ein wenig, aber wie lesbar wäre
werden? Nicht sehr. Speziell die Streicher in einem container finden würde es zu leicht zu stören seine string-Darstellung. Im Angesicht der Ungewissheit, denken Sie daran, Python widersteht der Versuchung, Sie zu erraten. Wenn Sie möchten, die oben beschriebenen Verhalten, wenn Sie drucken, eine Liste, nur
(kann man wohl auch herausfinden, was zu tun ist über Wörterbücher.
Zusammenfassung
Implementieren
__repr__
für jede Klasse, die Sie implementieren. Dies sollte zur zweiten Natur. Implementieren__str__
wenn Sie denken, es wäre sinnvoll, einen string-version, die Irrt auf der Seite der mehr Lesbarkeit zu Gunsten von mehr Unklarheit.InformationsquelleAutor der Antwort moshez
Meine Faustregel:
__repr__
ist für Entwickler__str__
ist für die Kunden.InformationsquelleAutor der Antwort Ned Batchelder
Es sei denn, Sie speziell zu handeln, um sicherzustellen, ansonsten sind die meisten Klassen nicht hilfreiche Ergebnisse für:
Wie Sie sehen-kein Unterschied, und keine info über die Klasse und Objekt
id
. Wenn Sie nur überschreiben Sie eine der beiden...:wie Sie sehen, wenn Sie überschreiben
__repr__
das ist AUCH für__str__
aber nicht Umgekehrt.Andere wichtige Leckerbissen zu wissen:
__str__
auf einem integrierten container verwendet die__repr__
NICHT die__str__
für die Elemente, die es enthält. Und trotz der Worte zu dem Thema gefunden, die in typischen docs, kaum jemand stört, macht die__repr__
von Objekten ein string sein, dereval
verwenden können zu bauen, die eine gleiche Objekt (es ist einfach zu schwer, UND nicht zu wissen, wie das relevante Modul wurde importiert, macht es eigentlich flat nicht möglich).Also, mein Rat: konzentrieren Sie sich auf die Herstellung
__str__
halbwegs lesbaren und__repr__
so eindeutig wie Sie nur können, selbst wenn, stört der unscharfe unerreichbares Ziel__repr__
's zurückgegebene Wert akzeptabel, die als input für__eval__
!InformationsquelleAutor der Antwort Alex Martelli
__repr__
: Darstellung von python-Objekt in der Regel eval wird es zu konvertieren zurück zu diesem Objekt__str__
: ist das, was Sie denken, ist das Objekt in text-formz.B.
InformationsquelleAutor der Antwort
Ist hier ein gutes Beispiel:
Lesen Sie diese Dokumentation für repr:
Hier ist die Dokumentation für str:
InformationsquelleAutor der Antwort bitoffdev
__str__
(Lesen als "dunder (doppelter Unterstrich) string") und__repr__
(Lesen als "dunder-repper" ("Darstellung")) sind spezielle Methoden, die Zeichenfolgen zurückgeben, basierend auf dem Zustand des Objekts.__repr__
bietet backup-Verhalten, wenn__str__
fehlt.Also sollte man zuerst schreiben Sie eine
__repr__
erlaubt, dass Sie instanziieren ein entsprechendes Objekt aus dem string-es gibt z.B. miteval
oder durch Eingabe Zeichen für Zeichen in eine Python-shell.Jederzeit später kann man schreiben, ein
__str__
für einen Benutzer lesbare string-Darstellung der Instanz, wenn man glaubt, dass es notwendig ist.__str__
Wenn Sie drucken ein Objekt, oder geben Sie Sie an
format
str.format
oderstr
dann, wenn ein__str__
Methode definiert ist, wird diese Methode aufgerufen, andernfalls__repr__
verwendet werden.__repr__
Den
__repr__
- Methode aufgerufen wird von der builtin-Funktionrepr
ist und was das echo auf Ihre python-shell, wenn es wertet einen Ausdruck, der ein Objekt zurückgibt.Da es bietet ein backup für
__str__
können, wenn man nur eins schreiben, beginnen Sie mit__repr__
Hier ist die eingebaute Hilfe auf
repr
:Dass ist für die meisten Objekte, wenn Sie geben in das, was gedruckt wird
repr
Sie sollten in der Lage sein erstellen Sie ein entsprechendes Objekt. Aber das ist nicht die default-Implementierung.Default-Implementierung von
__repr__
Den Standard -
__repr__
ist (C Python source) so etwas wie:Das bedeutet, standardmäßig werden Sie drucken das Modul, das Objekt, den Namen der Klasse, und die hexadezimale Darstellung seiner Lage im Speicher - Beispiel:
Diese Informationen nicht sehr nützlich, aber es gibt keine Möglichkeit ableiten, wie genau erstellen Sie eine kanonische Darstellung von einer bestimmten Instanz, und es ist besser als nichts, zumindest erzählen Sie uns, wie wir könnten, eindeutig zu identifizieren, es im Gedächtnis.
Wie kann
__repr__
nützlich sein?Schauen wir, wie nützlich es sein kann, mit Hilfe der Python-shell und
datetime
Objekte. Zunächst müssen wir importieren diedatetime
Modul:Wenn wir
datetime.now
in die Schale, wir sehen alles, wir müssen wieder eine äquivalente datetime-Objekt. Diese wird erstellt, indem die datetime -__repr__
:Wenn wir drucken ein datetime-Objekt, wir sehen ein schön menschlich lesbar (in der Tat, ISO) - format. Dies wird implementiert, indem datetime ist
__str__
:Ist es eine einfache Sache zu reproduzieren, ist das Objekt, das wir verloren, weil wir nicht einer variable zugewiesen, die durch kopieren und einfügen aus der
__repr__
Ausgang, und drucken Sie dann, und wir bekommen es in der gleichen human-readable Ausgabe als das andere Objekt:Wie kann ich Sie umsetzen?
Wie Sie zu entwickeln sind, werden Sie wollen, um in der Lage zu reproduzieren Objekte in den gleichen Zustand, wenn möglich. Diese, zum Beispiel, ist, wie die datetime-Objekt definiert
__repr__
(Python source). Es ist relativ Komplex, da alle Attribute benötigt, um zu reproduzieren, so ein Objekt:Wenn Sie möchten, dass Ihr Objekt, um eine besser lesbare Darstellung, die Sie umsetzen können
__str__
weiter. Hier ist, wie die datetime-Objekt (Python source) implementiert__str__
die es einfach tut, weil es bereits eine Funktion für die Anzeige im ISO-format:Set
__repr__ = __str__
?Dies ist eine Kritik von einer anderen Antwort hier, die nahelegt, dass die Einstellung
__repr__ = __str__
.Einstellung
__repr__ = __str__
ist dumm -__repr__
ist ein fallback für__str__
und ein__repr__
geschrieben für Entwickler, die Nutzung im debugging, geschrieben werden sollten, bevor Sie schreiben eine__str__
.Benötigen Sie eine
__str__
nur, wenn Sie müssen eine textuelle Repräsentation des Objekts.Abschluss
Definieren
__repr__
für Objekte, die Sie schreiben, so dass Sie und andere Entwickler haben ein reproduzierbares Beispiel, wenn Sie verwenden es, wie Sie sich entwickeln. Definieren__str__
wenn Sie müssen eine lesbare string-Darstellung.InformationsquelleAutor der Antwort Aaron Hall
In aller Ehrlichkeit,
eval(repr(obj))
ist nie benutzt. Wenn Sie sich finden, es zu benutzen, sollten Sie aufhören, weileval
ist gefährlich, und die Saiten sind eine sehr ineffiziente Art und Weise zu serialisieren von Objekten (Verwendungpickle
statt).Daher würde ich empfehlen, die Einstellung
__repr__ = __str__
. Der Grund dafür ist, dassstr(list)
Anruferepr
auf die Elemente (ich halte das für eine der größten design-Fehler von Python, wurde nicht behandelt Python 3). Eine tatsächlicherepr
wird wohl nicht sehr hilfreich, da die Ausgabe vonprint [your, objects]
.Relativieren, meiner Erfahrung nach, das nützlichste Anwendungsfall der
repr
- Funktion ist eine Zeichenfolge innerhalb einer anderen Zeichenfolge (mit string-Formatierung). Auf diese Weise brauchen Sie nicht zu befürchten, Flucht Zitate oder irgendetwas. Beachten Sie aber, dass es keineeval
hier passiert.InformationsquelleAutor der Antwort asmeurer
Abgesehen von all den Antworten, ich möchte hinzufügen, einige Punkte :-
1)
__repr__()
wird aufgerufen, wenn man schreibt einfach den Namen des Objekts auf der interaktiven python-Konsole und drücken Sie die EINGABETASTE.2)
__str__()
wird aufgerufen, wenn Sie mit dem Objekt mit der print-Anweisung.3) Im Fall, wenn
__str__
fehlt, dann drucken, und jede Funktion mitstr()
ruft__repr__()
des Objekts.4)
__str__()
von Containern, die beim Aufruf ausgeführt wird__repr__()
Methode der in Ihr enthaltenen Elemente.5)
str()
aufgerufen__str__()
potenziell recurse ohne Boden Falle, und Fehler, die auf maximale Rekursionstiefe.6)
__repr__()
nennen kannrepr()
die versuchen zu vermeiden, die eine unendliche Rekursion automatisch als Ersatz für eine bereits dargestellte Objekt mit...
.InformationsquelleAutor der Antwort Mangu Singh Rajpurohit
Um es einfach auszudrücken:
__str__
wird verwendet, um eine string-Darstellung des Objekts um leicht gelesen werden durch andere.__repr__
wird verwendet, um eine string-Darstellung des die Objekt.Sagen wir, ich möchte erstellen Sie eine
Fraction
Klasse, wo der string-Darstellung eines Bruchs '(1/2)' und das Objekt (die Bruch-Klasse) vertreten ist als 'Bruch (1,2)'So können wir eine einfache Bruch-Klasse:
InformationsquelleAutor der Antwort Zer0
Auf Seite 358 des Buches Python scripting for computational science von Hans Petter Langtangen, ist es klar, dass
__repr__
zielt auf einen vollständigen string-Darstellung des Objekts;__str__
ist die Rückgabe einer schön-string für das drucken.So, ich bevorzuge, um Sie zu verstehen, wie
aus der Sicht des Benutzers
obwohl das ist ein Missverständnis ich gemacht beim lernen von python.
Ein kleines, aber gutes Beispiel ist auch auf der gleichen Seite wie folgt:
Beispiel
InformationsquelleAutor der Antwort Yong Yang
Vom http://pyref.infogami.com/__str__ von effbot:
__str__
"berechnet die "informellen" string-Darstellung eines Objekts. Dies unterscheidet sich von__repr__
dass es sich nicht um ein gültiges Python-Ausdruck: ein bequemer oder übersichtliche Darstellung, können stattdessen verwendet werden."InformationsquelleAutor der Antwort Casebash
str
- Erstellt ein neues string-Objekt aus dem Objekt.repr
- Liefert die kanonische string-Darstellung des Objekts.Unterschiede:
str():
repr():
InformationsquelleAutor der Antwort Inconnu
Einen Aspekt, der fehlt in anderen Antworten. Es ist wahr, dass im Allgemeinen das Muster ist:
__str__
: human-readable__repr__
: eindeutige, möglicherweise maschinenlesbaren übereval
Leider diese Differenzierung ist fehlerhaft, da die Python-REPL und auch IPython verwenden
__repr__
für den Druck von Objekten in einer REPL-Konsole (siehe Verwandte Fragen für Python und IPython). Dadurch werden Projekte, die gezielt für die interaktive Konsole arbeiten (z.B. Numpy oder Pandas) haben begonnen, zu ignorieren, über Regeln und bieten eine lesbare__repr__
Umsetzung statt.InformationsquelleAutor der Antwort bluenote10
Ausgezeichnete Antworten decken bereits den Unterschied zwischen
__str__
und__repr__
die für mich darauf an, das ehemalige lesbar, auch durch einen Benutzer, und die letzteren, die so nützlich wie möglich an die Entwickler. Da finde ich, dass die default-Implementierung von__repr__
oft scheitert dieses Ziel zu erreichen, weil es lässt Informationen für Entwickler nützlich.Aus diesem Grund, wenn ich eine einfache genug
__str__
ich in der Regel einfach nur versuchen, das beste aus beiden Welten mit so etwas wie:InformationsquelleAutor der Antwort orome
Wenn die print() aufgerufen wird, auf das Ergebnis der Dezimalstellen.Decimal(23) /decimal.Dezimal("1.05") die raw-Zahl gedruckt, diese Ausgabe ist in string-formdie erreicht werden kann mit der __str __(). Wenn wir einfach geben Sie den Ausdruck ein, erhalten wir eine Dezimalzahl.Dezimal-Ausgabe—diese Ausgabe ist in Darstellungsformdie erreicht werden kann mit " __repr __(). Alle Python-Objekte haben zwei output-Formen. String-form ist entworfen, um lesbar sind. Darstellungsform ist entworfen, um zu produzieren Ausgabe, die, wenn gefüttert, um einen Python-interpreter würde (wenn möglich), re - produzieren die dargestellte Objekt
InformationsquelleAutor der Antwort BattleDrum
Python begünstigt Eindeutigkeit über die Lesbarkeitdie
__str__
Aufruf einertuple
ruft die enthaltenen Objekte__repr__
die "formale" Darstellung eines Objekts. Obwohl die formale Darstellung ist schwerer zu Lesen, als eine lose, es ist eindeutig und robuster gegen Fehler.InformationsquelleAutor der Antwort zangw
Aus dem Buch: Fließend Python
InformationsquelleAutor der Antwort Ijaz Khan
Kurz gesagt:
InformationsquelleAutor der Antwort ShadowWalker
Verstehen
__str__
und__repr__
intuitiv und dauerhaft unterscheiden.__str__
den string verkleidet Körper von einem gegebenen Objekt für lesbar Augen__repr__
Gegenzug echtes Fleisch Körper von einem gegebenen Objekt (sich selbst zurückgeben), für Eindeutigkeit zu identifizieren.Sehen es an einem Beispiel
Als zu
__repr__
Können wir tun, arithmetische operation auf
__repr__
Ergebnisse bequem.anwenden, wenn der Betrieb auf
__str__
Gibt nichts aber Fehler.
Weiteres Beispiel.
Hoffe, dass dies Ihnen dabei helfen, konkrete Gründe zu erkunden mehr Antworten.
InformationsquelleAutor der Antwort JawSaw
So viel klarer
von blog
str ist wie toString. erstellt, so können Sie die Daten drucken
repr ist wie serialisieren, oder Gurke. Wie kann ich neu dieses Objekt, wenn ich zu tun habe, also mit eval()
InformationsquelleAutor der Antwort Mickey Perlstein
__repr__
wird überall verwendet, außer durchprint
undstr
wenn ein__str__
definiert istInformationsquelleAutor der Antwort trthhrtz