简体   繁体   中英

Export JSON data from python objects

I'm trying to make a phone book in python and I want to save all contacts in a file, encoded as JSON, but when I try to read the exported JSON data from the file, I get an error:

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

( It works fine when I have only one object in "list.txt" )

This is my 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

The output in list.txt:

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

Now, if I add another object, it can't read the JSON data anymore. If my way of doing it is wrong, how else should I export the JSON code of every object in a class, so it can be read back when I need to?

The reason this isn't working is that this code path gives you an invalid JSON structure. With one contact you get this:

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

While with 2 contacts you would end up with this:

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

The second one is invalid json because 2 objects should be encoded in an array, like this:

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

The problem with your code design is that you're writing to the file every time you create a contact. A better idea is to create all contacts and then write them all to the file at once. This is cleaner, and will run more quickly since file I/O is one of the slowest things a computer can do.

My suggestion is to create a new class called Contact_Controller and handle your file IO there. Something like this:

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)

I've also changed it to use the built in __repr__() class method. Python will call that method whenever it needs a string representation of the object.

in writeJSON , you opened the file for append ( mode='a' ), which works fine the first time, but not the subsequent calls. To fix this problem, open the file with overwrite mode ( 'w' ):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM