2017-04-11 5 views
1

Ich versuche, ein Telefonbuch in Python zu erstellen, und ich möchte alle Kontakte in einer Datei speichern, codiert als JSON, aber wenn ich versuche, die exportierten JSON-Daten aus der Datei zu lesen, ich einen Fehler:JSON-Daten aus Python-Objekten exportieren

Extra data: line 1 column 103 - line 1 column 210 (char 102 - 209) 

(Es funktioniert gut, wenn ich nur ein Objekt in "list.txt" haben)

Dies ist mein Code:

class contacts: 
    def __init__(self, name="-", phonenumber="-", address="-"): 
     self.name= name 
     self.phonenumber= phonenumber 
     self.address= address 
     self.jsonData=json.dumps(vars(self),sort_keys=False, indent=4) 
     self.writeJSON(self.jsonData) 

    def writeJSON(self, jsonData): 
     with open("list.txt", 'a') as f: 
      json.dump(jsonData, f) 


ted=contacts("Ted","+000000000","Somewhere") 

with open('list.txt') as p: 
    p = json.load(p) 
    print p 

Die Ausgang in list.txt:

"{\n \"phonenumber\": \"+000000000\", \n \"name\": \"Ted\", \n \"address\": \"Somewhere\"\n}" 

Nun, wenn ich ein anderes Objekt hinzufügen, können sie nicht die JSON-Daten lesen mehr. Wenn meine Art, es zu tun, falsch ist, wie sonst sollte ich den JSON-Code jedes Objekts in einer Klasse exportieren, damit es bei Bedarf wieder gelesen werden kann?

Antwort

0

Der Grund dies nicht funktioniert ist, dass dieser Codepfad eine ungültige JSON Struktur. Mit einem Kontakt erhalten Sie folgendes:

{"name":"", "number":""}

Während mit 2 Kontakte würden Sie mit diesem Ende:

{"name":"", "number":""}{"name":"", "number":""}

Das zweite ist ungültig json weil zwei Objekte in ein codiertes werden soll Array, wie folgt aus:

[{"name":"", "number":""},{"name":"", "number":""}]

Das Problem wit Ihr Code-Design besteht darin, dass Sie jedes Mal, wenn Sie einen Kontakt erstellen, in die Datei schreiben. Eine bessere Idee ist es, alle Kontakte zu erstellen und dann alle in die Datei auf einmal zu schreiben. Dies ist sauberer und wird schneller ausgeführt, da Datei-I/O eines der langsamsten Dinge ist, die ein Computer ausführen kann.

Mein Vorschlag ist es, eine neue Klasse namens Contact_Controller zu erstellen und dort Ihre Datei IO zu behandeln. Etwas wie folgt aus:

import json 

class Contact_Controller: 
    def __init__(self): 
     self.contacts = [] 

    def __repr__(self): 
     return json.dumps(self) 

    def add_contact(self, name="-", phonenumber="-", address="-"): 
     new_contact = Contact(name,phonenumber,address) 
     self.contacts.append(new_contact) 
     return new_contact 

    def save_to_file(self): 
     with open("list.txt", 'w') as f: 
      f.write(str(self.contacts)) 

class Contact: 
    def __init__(self, name="-", phonenumber="-", address="-"): 
     self.name= name 
     self.phonenumber= phonenumber 
     self.address= address 

    def __repr__(self): 
     return json.dumps({"name": self.name, "phonenumber": self.phonenumber, "address": self.address}) 

contact_controller = Contact_Controller() 

ted = contact_controller.add_contact("Ted","+000000000","Somewhere") 
joe = contact_controller.add_contact("Joe","+555555555","Somewhere Else") 

contact_controller.save_to_file() 

with open('list.txt') as p: 
    p = json.load(p) 
    print(p) 

Ich habe mich verändert es auch die in __repr__() Klassenmethode gebaut zu verwenden. Python ruft diese Methode immer dann auf, wenn sie eine Zeichenfolgendarstellung des Objekts benötigt.

+0

Vielen Dank! Wenn ich auch eine Funktion hinzufügen möchte, die einen Kontakt löscht, also die JSON-Daten aus list.txt löscht (pop), was sollte mein Ansatz sein? Ich denke, ich weiß, wie man ein Element wie "Telefonnummer" entfernt, aber nicht, wie man das ganze Objekt entfernt (zum Beispiel alles über Joe entfernend) – C10H15N

+0

Sicher, das ist ziemlich einfach mit der Controller-Struktur. Fügen Sie der Klasse eine Funktion hinzu, um den Kontakt aus der Liste zu entfernen: 'def delete_contact (self, contact): self.contacts.remove (Kontakt)' Und am Ende der Datei löschen Sie "Joe": 'contact_controller.delete_contact (joe) contact_controller.save_to_file()' – CamJohnson26

0

in writeJSON, Sie öffneten die Datei zum Anhängen (mode='a'), die funktioniert das erste Mal, aber nicht die nachfolgenden Aufrufe. Um dieses Problem zu beheben, öffnen Sie die Datei mit Schreibmodus ('w'):

 with open("list.txt", 'w') as f: 
Verwandte Themen