Frage

Ich speichere den Anruf bei einer Klassenaufgabe in einem Array in einer .dat -Datei. Ich möchte diese Datei lesen und die Klassenanrufe rekonstruieren.

Hier ist die Klasse, die ich gerade benutze:

class Task:

    def __init__(self, name, timespent):
        self.name = name
        self.timespent = timespent

    def __repr__(self):
        return repr('Task("%s",%s)'%(self.name, self.timespent))

Hier ist die Lesung aus der Datei:

task_list = []
with open("task_list2.dat", "r") as file:
    task_list = eval(file.readline())

Hier ist das Schreiben in die Datei:

with open("task_list2.dat", "w") as outFile:
    print(repr(task_list), file = outFile)

Und hier ist der Inhalt der Datei:['Task("class",20)']Wo "Klasse" der Name der Aufgabe ist.

Ich verstehe, dass das Problem mit den einzelnen Zitaten um 'Aufgabe ("Klasse", 20) zu tun hat, aber ich habe keine Ahnung, wie ich sie loswerden soll. Die Fehlermeldung, die ich erhalte, sagt etwas in den Zeilen: "STR -Objekt hat keinen Attributnamen" "

Wie kann ich diese Zitate entfernen, damit ich die Klassen beim nächsten Mal, als ich die Datei lese, rekonstruieren kann?

War es hilfreich?

Lösung

Sie wollen wirklich, wirklich, wirklich nicht versuchen zu verwenden repr und eval als Serialisierungsformat.

Wenn Sie nur benutzt haben, sagen wir, pickle, Sie hätten dieses Problem überhaupt nicht:

with open("task_list2.dat", "wb") as outFile:
    pickle.dump(task_list, outFile)

with open("task_list2.dat", "rb") as file:
    task_list = pickle.load(file)

Viel einfacher, ja?


Aber wenn Sie wissen möchten, wie Sie das unmittelbare Problem lösen können, anstatt es irrelevant zu machen: Sie haben mehrere Probleme in Ihrem __repr__ Methode, die alle repariert werden müssen, wenn Sie möchten, dass sie rundum gerührt werden.

  • Sie generieren eine String -Darstellung… und rufen dann an repr darauf. Sie möchten die String -Darstellung zurückgeben, nicht eine String -Darstellung von die String -Darstellung. Lass einfach das weg repr.
  • Sie sollten immer an die delegieren repr von Unterobjekten, nicht der str. Wenn Sie verwenden %-Formatieren bedeutet die Verwendung %r statt %s.
  • Versuchen Sie nicht, Zitate um Dinge hinzufügen. Das mag passieren, wenn das Objekt selbst keine Zitate, Backslashes, unsichtbare Zeichen usw. enthält, aber warum jedoch darauf angewiesen ist? Wenn Sie der Meinung sind, dass Sie Zitate benötigen, ist es so ziemlich immer ein Zeichen dafür, dass Sie die vorherige Regel gebrochen haben, und Sie sollten das stattdessen beheben.

So können Sie für diese Klasse eine rundumstreckbare Repr schreiben:

def __repr__(self):
    return 'Task(%r, %r)' % (self.name, self.timespent))

Und Sie können überprüfen, ob es das tut, was Sie wollen:

>>> t = Task('task name', 23.4)
>>> t
Task('task name', 23.4)
>>> eval(repr(t))
Task('task name', 23.4)

Natürlich in Ihrem speziellen Beispiel nur das erste Problem behoben (Entfernen des falschen Anrufs an repr) hätte die einzelnen Zitate losgeworden und dieses bestimmte Beispiel zum Laufen gebracht. Sie können das auch auf der Leseseite durchrufen, indem Sie anrufen eval zweimal. Oder für dieses spezielle Beispiel auch durch Anrufe eval(s[1:-1]) oder eval(s.strip("'")). Aber jeder "Fix" wie diese wird es nur schwerer machen, die allgemeinen Probleme zu debuggen, auf die Sie begegnen werden, z. B. einen Namen, der nicht so einfach ist wie ein einzelnes All-Ascii-Letter-Wort.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top