it-swarm.com.de

Python-Objekt .__ repr__ (selbst) sollte ein Ausdruck sein?

Ich habe mir die eingebauten Objektmethoden in der Python-Dokumentation angesehen , und ich interessierte mich für die Dokumentation für object.__repr__(self). Folgendes sagt es:

Wird von der eingebauten Funktion repr () aufgerufen und durch String-Konvertierungen (umgekehrte Anführungszeichen), um den "offiziellen" Zeichenfolgendarstellung eines Objekts. Ob möglichst sollte dies aussehen ein gültiger Python-Ausdruck, der kann verwendet werden, um ein Objekt mit der .__ neu zu erstellen. gleicher Wert (bei entsprechender Umgebung). Wenn dies nicht möglich ist, eine Zeichenfolge der Form <... einige nützliche Beschreibung ...> sollte zurückgegeben werden . Der Rückgabewert muss eine Zeichenfolge sein Objekt. Wenn eine Klasse repr () .__ definiert. aber nicht str (), dann ist repr () Wird auch verwendet, wenn eine "informelle" Zeichenfolge Darstellung von Instanzen davon Klasse ist erforderlich.

Dies wird normalerweise zum Debuggen verwendet. Daher ist es wichtig, dass die Darstellung ist reich an Informationen und eindeutig

Der interessanteste Teil für mich war ...

Wenn überhaupt möglich, sollte dies wie ein gültiger Python-Ausdruck aussehen, mit dem ein Objekt mit demselben Wert erneut erstellt werden kann

... aber ich weiß nicht genau was das bedeutet. Es sagt, es sollte look wie ein Ausdruck sein, der zum Wiederherstellen des Objekts verwendet werden kann, bedeutet aber, dass es nur ein Beispiel für die Art des Ausdrucks sein sollte, den Sie verwenden könnten, oder sollte es ein tatsächlicher Ausdruck sein. das ausgeführt werden kann (eval etc ..), um das Objekt neu zu erstellen? Oder ... sollte es nur eine Umformung des tatsächlichen Ausdrucks sein, der zu reinen Informationszwecken verwendet wurde?

Im Allgemeinen bin ich etwas verwirrt, was genau ich hier einstellen sollte.

67
Alex McBride
>>> from datetime import date
>>>
>>> repr(date.today())        # calls date.today().__repr__()
'datetime.date(2009, 1, 16)'
>>> eval(_)                   # _ is the output of the last command
datetime.date(2009, 1, 16)

Die Ausgabe ist eine Zeichenfolge, die vom Python-Interpreter analysiert werden kann und zu einem gleichwertigen Objekt führt.

Wenn dies nicht möglich ist, sollte eine Zeichenfolge in der Form von <...some useful description...> zurückgegeben werden.

62
Georg Schölly

Es sollte ein Python-Ausdruck sein, der bei der Auswertung ein Objekt mit denselben Eigenschaften wie dieses erstellt. Wenn Sie beispielsweise eine Fraction-Klasse haben, die zwei Ganzzahlen enthält, einen Zähler und einen Nenner, würde Ihre __repr__()-Methode folgendermaßen aussehen:

# in the definition of Fraction class
def __repr__(self):
    return "Fraction(%d, %d)" % (self.numerator, self.denominator)

Angenommen, der Konstruktor nimmt diese beiden Werte an.

31
Jeremy Ruten

Richtlinie: Wenn Sie eine genaue Darstellung bereitstellen können, formatieren Sie sie als Python expression (was impliziert, dass es im richtigen Kontext sowohl ausgewertet als auch direkt in den Quellcode kopiert werden kann). Wenn Sie eine ungenaue Darstellung angeben, verwenden Sie das <...>-Format.

Es gibt viele mögliche Darstellungen für jeden Wert, aber die für Python Programmierer interessanteste ist ein Ausdruck, der den Wert neu erstellt. Denken Sie daran, dass diejenigen, die Python verstehen, die Zielgruppe sind - und deshalb sollten ungenaue Darstellungen auch den relevanten Kontext enthalten. Sogar der voreingestellte <XXX object at 0xNNN> bietet, obwohl er fast völlig nutzlos ist, den Typ id() (zur Unterscheidung verschiedener Objekte) und den Hinweis, dass keine bessere Darstellung verfügbar ist.

12
Roger Pate

"Aber bedeutet das, dass es nur ein Beispiel für die Art von Ausdruck sein sollte, die Sie verwenden könnten, oder sollte es ein tatsächlicher Ausdruck sein, der ausgeführt werden kann (eval usw.), um das Objekt neu zu erstellen? Oder ... sollte es sein nur ein rehasing des tatsächlichen Ausdrucks, der zu reinen Informationszwecken verwendet wurde? "

Wow, das ist viel Handarbeit.

  1. Ein "Beispiel für die Art von Ausdruck, den Sie verwenden könnten" wäre keine Darstellung eines bestimmten Objekts. Das kann nicht nützlich oder sinnvoll sein. 

  2. Was ist der Unterschied zwischen "einem tatsächlichen Ausdruck, der ... das Objekt neu erstellen kann" und "einer Neuausrichtung des tatsächlichen Ausdrucks, der verwendet wurde [um das Objekt zu erstellen]"? Beide sind ein Ausdruck, der das Objekt erstellt. Es gibt keinen praktischen Unterschied zwischen diesen. Ein Repräsentationsaufruf kann entweder einen neuen Ausdruck oder den ursprünglichen Ausdruck erzeugen. In vielen Fällen sind sie gleich.

Beachten Sie, dass dies nicht immer möglich, praktisch oder wünschenswert ist.

In einigen Fällen werden Sie feststellen, dass repr () eine Zeichenfolge darstellt, die eindeutig nicht ein Ausdruck jeglicher Art ist. Die Standardeinstellung repr () für jede von Ihnen definierte Klasse ist als Ausdruck nicht nützlich.

In einigen Fällen haben Sie möglicherweise gegenseitige (oder kreisförmige) Verweise zwischen Objekten. Das repr () dieser verworrenen Hierarchie macht keinen Sinn.

In vielen Fällen wird ein Objekt über einen Parser inkrementell erstellt. Zum Beispiel von XML oder JSON oder etwas. Was wäre der Repräsentant? Das ursprüngliche XML oder JSON? Natürlich nicht, da es sich nicht um Python handelt. Es könnte ein Python-Ausdruck sein, der XML generiert hat. Für ein gigantisches XML-Dokument ist es jedoch möglicherweise nicht möglich, einen einzelnen Python-Ausdruck zu schreiben, der das funktionale Äquivalent zum Analysieren von XML darstellt.

4
S.Lott

Um zu sehen, wie der Repräsentant innerhalb einer Klasse funktioniert, führen Sie den folgenden Code aus, zuerst mit und dann ohne die Methode repr

class Coordinate (object):
    def __init__(self,x,y):
        self.x = x
        self.y = y

    def getX(self):
        # Getter method for a Coordinate object's x coordinate.
        # Getter methods are better practice than just accessing an attribute directly
        return self.x
    def getY(self):

        # Getter method for a Coordinate object's y coordinate
        return self.y

    def __repr__(self):  #remove this and the next line and re-run
        return 'Coordinate(' + str(self.getX()) + ',' + str(self.getY()) + ')' 

>>>c = Coordinate(2,-8)
>>>print(c)
1
Saeed Ahmed

'repr' bedeutet Repräsentation . Zuerst erstellen wir eine Instanz von Klassenkoordinaten.

x = Coordinate(3, 4) 

Wenn wir dann x in die Konsole eingeben, ist die Ausgabe 

<__main__.Coordinate at 0x7fcd40ab27b8>

Wenn Sie repr () verwenden:

>>> repr(x)
Coordinate(3, 4)

die Ausgabe entspricht der von 'Koordinate (3, 4)', es sei denn, es handelt sich um eine Zeichenfolge. Sie können damit eine Instanz von Koordinaten neu erstellen.

Im Ergebnis wird repr () meathod eine Zeichenfolge ausgegeben, die die Darstellung des Objekts darstellt.

1
zhenXiongChen

Ich denke, dass die Verwirrung hier aus dem Englischen stammt. Ich meine __repr__(); kurz für "Darstellung" des Werts, den ich schätze, wie @ S.Lott sagte 

"Was ist der Unterschied zwischen" einem tatsächlichen Ausdruck, der ... das Objekt neu erstellen kann "und" einer Neuberechnung des tatsächlichen Ausdrucks, der verwendet wurde [um das Objekt zu erstellen] "? Beide sind ein Ausdruck, der das Objekt erstellt praktische Unterscheidung zwischen diesen. Eine Repräsentation kann entweder einen neuen Ausdruck oder den ursprünglichen Ausdruck erzeugen. In vielen Fällen sind sie gleich. "

In manchen Fällen können sie jedoch unterschiedlich sein. Z.B; Koordinatenpunkte können Sie c.coordinate zurückgeben: 3,5, aber c.__repr__, um Coordinate(3, 5) zurückzugeben Hoffe das macht mehr Sinn ... 

0
sle7en