在Python中将JSON字符串反序列化为对象

时间:2016-03-06 13:27:46

标签: python json

我编写了这段代码来保存对象并将其加载到JSON中。 当我访问属性时,我遇到了这个错误:

我使用python json类来序列化对象并反序列化它。

属性错误:' dict'对象没有属性' weeknumber'

# -*- coding: utf-8 -*-
import pickle
import pprint
from datetime import date
import datetime
import decimal
import json


class Jsonable(object):
    def __iter__(self):
        for attr, value in self.__dict__.iteritems():
            if isinstance(value, datetime.datetime):
                iso = value.isoformat()
                yield attr, iso
            elif isinstance(value, decimal.Decimal):
                yield attr, str(value)
            elif(hasattr(value, '__iter__')):
                if(hasattr(value, 'pop')):
                    a = []
                    for subval in value:
                        if(hasattr(subval, '__iter__')):
                            a.append(dict(subval))
                        else:
                            a.append(subval)
                    yield attr, a
                else:
                    yield attr, dict(value)
            else:
                yield attr, value


class MyCalendar(Jsonable):
    year = 0
    weeks = {}
    def __init__(self, _year,_weeks):
        self.year = _year
        self.weeks = _weeks;

class MyWeek(Jsonable):
    weeknumber = 0
    days = {}
    def __init__(self, _week,_days):
        self.weeknumber = _week   
        self.days = _days 

class MyDay(Jsonable):
    daynumber = 0
    courses = {}
    def __init__(self, _day,_courses):
        self.daynumber = _day  
        self.courses = _courses

class MyCourse(Jsonable):
    id = 0
    title = ''
    def __init__(self, _id,_title):
        self.id = _id 
        self.title = _title                  



def init():
    _myc = MyCalendar(date.today().year,[]);
    for wi in range(0, 52):
        _week = MyWeek(wi,[])
        for di in range(0, 5):
            _day = MyDay(di,[])
            for ci in range(0, 4):
                _course = MyCourse(ci,"empty")
                _day.courses.append(_course)
            _week.days.append(_day)
        _myc.weeks.append(_week)
    return _myc

def save(_t):
    with open('data2.txt', 'w') as outfile:
        json.dump(dict(_t), outfile)

def load():  
    _t =  init();
    with open('data2.txt', 'r') as infile:
        _t.__dict__ = json.loads(infile.read())
    return _t

def setCourse(_t,_weeknumnber,_dayumber,_course,_title): 
    _t.weeks[_weeknumnber].days[_dayumber].courses[_course].title  = _title
    return _t

_mycal = init();


setCourse(_mycal,1,2,3,"Python");
save(_mycal)
_mycal = load()
pprint.pprint( _mycal.weeks[1].weeknumber)

1 个答案:

答案 0 :(得分:1)

您的代码本质上是正确的,但是您混合了很多方面并以丑陋的方式解析JSON,从而为您提供当前结果,您无法直接访问属性但是您可以处理对象创建为字典,需要通过密钥访问它。为了实现自己的方式,并保持属性,您需要为类创建自己的解析器。我已经在我的工作区中快速复制了代码:

import json

class MyCalendar:
    def __init__(self, _year, _weeks):
        self.year = _year
        self.weeks = _weeks

    def to_JSON(self):
        # Dumps the JSON correctly, passing over the __dict__ of the class to assmble it.
        return json.dumps(self, default=lambda o: o.__dict__)

class MyWeek:
    def __init__(self, _week, _days):
        self.weeknumber = _week
        self.days = _days

class MyDay:
    def __init__(self, _day, _courses):
        self.daynumber = _day
        self.courses = _courses

class MyCourse:
    def __init__(self, _id, _title):
        self.id = _id
        self.title = _title

def json_calendar(dct):
    year = dct['year'] # year, for quick reference.
    weeks = {} # our weeks, as a dict.

    for week in dct['weeks']: # iterate through the available weeks in the given dct.
        days = {} # our days, as a dict.
        for day in dct['weeks'][week]['days']: # iterate through the available days in the week.
            courses = {} # our courses, as a dict.
            for course in dct['weeks'][week]['days'][day]['courses']: # iterate through the available courses in the day.
                courseId = int(course) # course id
                courseTitle = dct['weeks'][week]['days'][day]['courses'][course]['title'] # course title

                courses[courseId] = MyCourse(courseId, courseTitle) # Assemble our courses into the courses dict.

            days[int(day)] = MyDay(day, courses) # Assemble our days into the day dict.

        weeks[int(week)] = MyWeek(week, days) # Assemble our weeks into the weeks dict.

    return MyCalendar(year, weeks) # Assemble and return our calendar.

现在您可以简单地创建日历,现在当您要转储它时,您只需要执行_mycal.To_JSON()并从您需要执行的JSON中获取日历对象{{1}因为我们在特定的解析器中解析了它,所以你可以毫无问题地访问这些属性。