Python3字典样式对象映射到JSON Serializableable

时间:2017-09-05 19:21:52

标签: python json serialization

我正在研究一个简单的员工系统,用于学习Python3中的面向对象编程。 我的脚本按预期工作,不包括保存和加载员工字典。 问题是我的字典不是这段代码的正常字典原因: Employees[eid] = Employee(eName,eSalary,eAge) 我想让这个数据库JSON Serializeable,但我不知道,也没有在互联网上找到它。

遗憾的是,堆栈溢出中的代码添加系统给了我癌症所以我将我的代码粘贴到gist: https://gist.github.com/ShockvaWe/d82d89f767506c1ff682a4cc387d1597

我的当前代码的错误消息是(它的基本TypeEroor但是......): 抱歉,但是我浪费了2个小时试图粘贴我的代码而我失败了所以我生气了。谢谢编辑和答案。

以下是代码:

## -*- coding=<utf-8> -*-
import json 
from json import JSONEncoder
Employees = {}
print(type(Employees))
class Employee(object): 
    'Common base for all employes'
    empCount = 0
    def __init__(self,name,salary,age): 
        self.name = name
        self.salary = salary
        self.age = age
        Employee.empCount += 1

    def displayCount(self):
        print ("Total Employee : " , Employee.empCount , "\n")

    def displayEmployee(self):
        print("Name : ", self.name ," Salary : " , self.salary ," Age : " , self.age, "\n")
print ("NEVER FORGET TO SAVE YOUR CHANGES ! \n")
print ("Press s to save your work ! \n")
print ("Press l to load database. \n")
print ("Press x for adding employee \n")
print ("Press y for show employee count \n")
print ("Press z for display employee \n")
print ("Press q for quitting. \n")
while True :
    st = input("->> : ")
    if (st == "x"):
        eid = input ("Id : ")
        eName = input ("\nName : ")
        eSalary = input ("\nSalary : ")
        eAge = input ("\nAge : \n")
        Employees[eid] = Employee(eName,eSalary,eAge)
    if (st == "y"):
        print("Total Employee Count : " , Employee.empCount)
    if (st == "z"):
        wantedId = input("Give the id : ")
        Employees[wantedId].displayEmployee()
    if (st == "q"):
        exit()
    if (st == "s"):
        with open('myfile.json','w') as f:
            json.dump(dict(Employees),f)
    if (st == "l"):
        with open('myfile.json') as f:
            Employees = json.load(f)
    if (st == 'f'):
        print("roger dodger")

1 个答案:

答案 0 :(得分:0)

这是一个可能重现你所看到的TypeError的小例子:

class Foo(object):
  def __init__(self, arg):
    self.arg = arg

d = {'key1': Foo('some arg')}
import json

print json.dumps(d)

就其性质而言,Python class实例不可序列化。假设您想要类中的数据,一个选项是使用实例字典而不是类对象:

class Foo(object):
  def __init__(self, arg):
    self.arg = arg

f = Foo('some arg')
d = {'key1': f.__dict__}
import json

print json.dumps(d)

结果:

{"key1": {"arg": "some arg"}}

要反序列化,您可以在数据库中使用序列并使其构建新的Employee对象,并在以后“重构”它们时在JSON中跟踪它:

import json

class Employee(object):
  def __init__(self, arg, emp_id=None):
    self.emp_id = emp_id or self.get_id()
    self.arg = arg

  def get_id(self):
    """
    This example assumes you have a db query module and some kind of Sequence 
    definition that looks like this (I am using postgres here) :

      Sequence "your_app.employee_id_seq"
        Column     |  Type   |          Value           
    ---------------+---------+--------------------------
     sequence_name | name    | employee_id_seq
     last_value    | bigint  | 1204
     start_value   | bigint  | 1
     increment_by  | bigint  | 1
     max_value     | bigint  | 9223372036854775807
     min_value     | bigint  | 1
     cache_value   | bigint  | 1
     log_cnt       | bigint  | 31
     is_cycled     | boolean | f
     is_called     | boolean | t
    """
    return your_db_module.query("SELECT nextval('employee_id_seq'::regclass)")

测试:

f = Employee('some arg')
d = {f.emp_id: f.__dict__}
# We could add as many employees as we like to serialized, but I am just using one here:
serialized = json.dumps(d)
deserialized_employees = json.loads(serialized)
print deserialized_employees
employee_objects = []
for k, v in deserialized_employees.items():
  # assert int(k) == int(v['emp_id']) - a check if you want to be paranoid
  # Now that we have an ID, we can use the kwarg for emp_id to construct the right object
  e = Employee(v['arg'], emp_id=int(k))
  employee_objects.append(e)

print employee_objects[0]

结果:

<__main__.Employee object at 0x10dca6b50>

请注意,您可能需要定义自定义__cmp__和/或__eq__方法,以便让您的唯一emp_id成为唯一员工的定义特征,因为此时此在技​​术上,我们允许使用单个ID创建同一员工的许多实例(通常是坏事。)不确定这是否会对您的案例发挥作用,但值得考虑。