2017-04-11 43 views
1

我想在python中创建一个电话簿,并且我想将所有联系人保存在文件中,编码为JSON,但是当我尝试从文件中读取导出的JSON数据时,我得到一个错误:从Python对象导出JSON数据

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

它正常工作时,我在 “LIST.TXT”只有一个对象)

这是我的代码:

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 

输出在LIST.TXT:

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

现在,如果我添加另一个对象,它无法读取JSON数据了。如果我的做法是错误的,我应该如何导出类中每个对象的JSON代码,以便在需要时可以回读它?

回答

0

这是不工作的原因是,该代码路径为您提供了一个无效的JSON结构。有了一个接触,你会得到:

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

虽然有2个触点,你最终会得到这样的:

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

第二个是无效的JSON,因为2个对象应在编码阵列,这样的:

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

问题机智h您的代码设计是每次创建联系人时都要写入文件。一个更好的想法是创建所有联系人,然后将它们全部写入文件中。由于文件I/O是计算机能够做的最慢的事情之一,因此它更干净,并且运行速度更快。

我的建议是创建一个名为Contact_Controller的新类,并在那里处理文件IO。这样的事情:

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) 

我也改变它使用内置__repr__()类的方法。只要需要对象的字符串表示形式,Python就会调用该方法。

+0

谢谢!如果我还想添加一个删除联系人的函数,这意味着它从list.txt中删除(弹出)JSON数据,这应该是我的方法吗?我想我知道如何删除像“电话号码”这样的元素,但不知道如何删除整个对象(例如,删除有关'Joe'的所有内容) – C10H15N

+0

当然,控制器结构非常简单。向类中添加一个函数以从列表中删除联系人: 'def delete_contact(self,contact):self.contacts.remove(contact)' 并在文件结尾处删除“Joe”: 'contact_controller.delete_contact(joe)contact_controller.save_to_file()' – CamJohnson26

0

in writeJSON,您打开了追加文件(mode='a'),该文件第一次正常工作,但不是后续调用。要解决这个问题,打开与覆盖模式('w')文件:

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