【问题标题】:Python3 Dictionary Style Object Mapping To JSON SerializeablePython3 字典样式对象映射到 JSON 可序列化
【发布时间】:2017-09-05 19:21:52
【问题描述】:

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

遗憾的是,堆栈溢出中的代码添加系统让我患上了癌症,所以我将代码粘贴到 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")

【问题讨论】:

  • 如果你想回答你的问题,你可能不应该侮辱你发布它的网站。我建议编辑你的帖子更有礼貌。
  • 请编辑您的问题并删除最后一段。它令人反感,与您的问题无关。尝试再次编辑它并包含您的代码。你知道,很多人使用这个网站并且可以写出格式正确的问题

标签: python json serialization


【解决方案1】:

这里有一个小例子,可能重现了您所看到的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 创建同一员工的多个实例(通常是一件坏事。)不确定这是否会对您的情况起作用,但值得考虑。

【讨论】:

  • 是的,但是现在如何将其反序列化回正确的对象?
  • 由于这与数据库有关,我建议使用自动递增序列作为 Employee 的唯一标识符,然后将其传递到每个对象的初始化中,并以此为基础用于稍后反序列化。您可以简单地根据您拥有的 dict 构造员工。
  • 你也可以反序列化吗?
  • 是的 @NickyRomero - 我将添加一个 get_id() 方法并显示一个用于 id 的示例数据库设置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多