Welches ist ein besserer __Repr__ für eine benutzerdefinierte Python -Klasse?
-
28-10-2019 - |
Frage
Es scheint, dass es verschiedene Möglichkeiten gibt, die __repr__
Funktion kann zurückkehren.
Ich habe eine Klasseninfoobj, die eine Reihe von Dingen speichert, von denen einige nicht besonders möchte, dass Benutzer der Klasse selbst festlegen. Ich erkenne, dass nichts in Python geschützt ist, und sie könnten einfach eintauchen und es trotzdem einstellen, aber es scheint es zu definieren, es in __init__
Macht es wahrscheinlicher, dass jemand es sieht und annimmt, dass es in Ordnung ist, es einfach einzugeben.
(Beispiel: Booleans, die durch eine Validierungsfunktion festgelegt werden, wenn feststellt A und B werden eingestellt, dann wird C berechnet und das Objekt gültig markiert = true.)
Also, angesichts all dessen, was ist der beste Weg, um die Ausgabe von __ repr__ zu entwerfen?
bob = InfoObj(Name="Bob")
# Populate bob.
# Output type A:
bob.__repr__()
'<InfoObj object at 0x1b91ca42>'
# Output type B:
bob.__repr__()
'InfoObj(Name="Bob",Pants=True,A=7,B=5,C=2,Valid=True)'
# Output type C:
bob.__repr__()
'InfoObj.NewInfoObj(Name="Bob",Pants=True,A=7,B=5,C=2,Valid=True)'
... Der Punkt vom Typ C wäre darin, nicht alle Dinge, die ich "privat" in C ++ als Argumente festlegen würde für Sie. In diesem Fall würde ich einen Konstruktor definieren, der bestimmte Dinge nicht einnimmt, und eine separate Funktion, die für die Zwecke von etwas schwieriger zu bemerken ist __repr__
Wenn es einen Unterschied macht, habe ich vor, diese Python -Objekte in einer Datenbank mithilfe ihrer zu speichern __repr__
Ausgabe und abrufen mithilfe eval()
, Zumindest, wenn ich keinen besseren Weg habe. Die Folge eines Teamkollegen, das manuell ein vollständiges Objekt erstellt, anstatt die richtigen Schnittstellenfunktionen zu durchlaufen, ist nur die Art des Abrufens von Informationen möglicherweise instabil, bis jemand herausfindet, was er getan hat.
Lösung
Das __repr__
Die Methode wurde entwickelt, um die nützlichste Ausgabe für den Entwickler zu erzeugen, nicht für den Enduser. Nur Sie können diese Frage wirklich beantworten. Normalerweise würde ich jedoch Option B. Option A nicht sehr nützlich machen, und Option C ist unnötig ausführlich - Sie wissen nicht, wie Ihr Modul ohnehin importiert wird. Andere bevorzugen Option C.
Wenn Sie jedoch Python -Objekte speichern möchten, ist eine Datenbank, verwenden Sie pickle
.
import pickle
bob = InfoObj(Name="Bob")
> pickle.dumps(bob)
b'...some bytestring representation of Bob...'
> pickle.loads(pickle.dumps(bob))
Bob(...)
Wenn Sie ältere Python (Pre-3.x) verwenden, beachten Sie dies cPickle
ist schneller, aber pickle
ist erweiterbarer. Pickle funktioniert ohne Konfiguration an einigen Ihrer Klassen, aber für kompliziertere Objekte möchten Sie möglicherweise benutzerdefinierte Auszahlen schreiben.