技术频道导航
HTML/CSS
.NET技术
IIS技术
PHP技术
Js/JQuery
Photoshop
Fireworks
服务器技术
操作系统
网站运营

赞助商

分类目录

赞助商

最新文章

搜索

4种方法使Python类JSON可序列化

作者:admin    时间:2021-12-29 8:41:11    浏览:

有多种方法可以使 Python 类 JSON 可序列化,本文将介绍4种方法使 Python 类 JSON 可序列化,你可以选择最适合你的一种。

 解释了如何使 Python 类 JSON 可序列化
解释了如何使 Python 类 JSON 可序列化

编写自定义 JSONEncoder 使类 JSON 可序列化

Python json 模块有一个JSONEncoder类。如果你想要更多自定义输出,你可以扩展它,即你必须继承 JSONEncoder,以便你可以实现自定义 JSON 序列化。

JSON 模块的json.dump()json.dumps()方法有一个cls kwarg。使用这个参数,你可以传递一个自定义的 JSON 编码器,它告诉json.dump()json.dumps()方法如何将你的对象编码为 JSON 格式的数据。默认的 JSONEncoder 类有一个default()方法,当我们执行JSONEncoder.encode(object),此方法仅将基本类型转换为 JSON。

你的自定义 JSONEncoder 子类将覆盖该default()方法以序列化其他类型。使用json.dumps()方法的cls kwarg指定它,否则,将使用默认的 JSONEncoder。例子:json.dumps(cls=CustomEncoder)。现在让我们看看这个例子。

import json
from json import JSONEncoder

class Employee:
    def __init__(self, name, salary, address):
        self.name = name
        self.salary = salary
        self.address = address

class Address:
    def __init__(self, city, street, pin):
        self.city = city
        self.street = street
        self.pin = pin

# subclass JSONEncoder
class EmployeeEncoder(JSONEncoder):
        def default(self, o):
            return o.__dict__

address = Address("Alpharetta", "7258 Spring Street", "30004")
employee = Employee("John", 9000, address)

print("Printing to check how it will look like")
print(EmployeeEncoder().encode(employee))

print("Encode Employee Object into JSON formatted Data using custom JSONEncoder")
employeeJSONData = json.dumps(employee, indent=4, cls=EmployeeEncoder)
print(employeeJSONData)

# Let's load it using the load method to check if we can decode it or not.
print("Decode JSON formatted Data")
employeeJSON = json.loads(employeeJSONData)
print(employeeJSON)

输出:

Printing to check how it will look like
{"name": "John", "salary": 9000, "address": {"city": "Alpharetta", "street": "7258 Spring Street", "pin": "30004"}}

Encode Object into JSON formatted Data using custom JSONEncoder
{
    "name": "John",
    "salary": 9000,
    "address": {
        "city": "Alpharetta",
        "street": "7258 Spring Street",
        "pin": "30004"
    }
}

Decode JSON formatted Data
{'name': 'John', 'salary': 9000, 'address': {'city': 'Alpharetta', 'street': '7258 Spring Street', 'pin': '30004'}}

注意:

  • EmployeeEncoder 类覆盖了类的default()方法JSONEncoder,因此我们能够将自定义 Python 对象转换为 JSON。
  • EmployeeEncoder 类中,我们将对象转换为 Python 字典格式。

使用 toJSON() 方法使类 JSON 可序列化

一个简单直接的解决方案,我们可以在类中实现一个序列化器方法,而不是使类 JSON 可序列化。

所以我们不需要编写自定义的 JSONEncoder

这个新的toJSON()序列化器方法将返回对象的 JSON 表示,即它将自定义Python对象转换为JSON字符串。让我们看看例子。

import json

class Employee:
    def __init__(self, name, salary, address):
        self.name = name
        self.salary = salary
        self.address = address

    def toJson(self):
        return json.dumps(self, default=lambda o: o.__dict__)

class Address:
    def __init__(self, city, street, pin):
        self.city = city
        self.street = street
        self.pin = pin

address = Address("Alpharetta", "7258 Spring Street", "30004")
employee = Employee("John", 9000, address)

print("Encode into JSON formatted Data")
employeeJSONData = json.dumps(employee.toJson(), indent=4)
print(employeeJSONData)

# Let's load it using the load method to check if we can decode it or not.
print("Decode JSON formatted Data")
employeeJSON = json.loads(employeeJSONData)
print(employeeJSON)

输出:

Encode into JSON formatted Data
"{\"name\": \"John\", \"salary\": 9000, \"address\": {\"city\": \"Alpharetta\", \"street\": \"7258 Spring Street\", \"pin\": \"30004\"}}"

Decode JSON formatted Data
{"name": "John", "salary": 9000, "address": {"city": "Alpharetta", "street": "7258 Spring Street", "pin": "30004"}}

注意:

如你所见,我们能够将 Employee 对象编码和解码为 JSON 格式的流。

我们使用json.dumps()方法的default参数将附加类型序列化为 dict 并将新创建的 dict 转换为 JSON 字符串。

使用 jsonpickle 模块使类 JSON 可序列化

jsonpickle 是一个 Python 库,旨在处理复杂的 Python 对象。你可以使用 jsonpickle 将复杂的 Python 对象序列化为 JSON。此外,还有从 JSON 反序列化到复杂的 Python 对象。

如你所知,Python的内置json 模块只能处理具有直接 JSON 等效项的 Python 原语类型(例如,字典、列表、字符串、数字、无等)。

jsonpickle 构建在这些库之上,并允许将更复杂的数据结构序列化为 JSON。jsonpickle 是高度可配置和可扩展的——允许用户选择 JSON 后端并添加额外的后端。

步骤:

  • 安装 jsonpickle 使用 pip install jsonpickle
  • 执行jsonpickle.encode(object)以序列化自定义 Python 对象。
     

你可以参考Jsonpickle 文档了解更多详细信息。让我们看一下 jsonpickle 示例,使 Python 类 JSON 可序列化。

import json
import jsonpickle
from json import JSONEncoder

class Employee(object):
    def __init__(self, name, salary, address):
        self.name = name
        self.salary = salary
        self.address = address

class Address(object):
    def __init__(self, city, street, pin):
        self.city = city
        self.street = street
        self.pin = pin

address = Address("Alpharetta", "7258 Spring Street", "30004")
employee = Employee("John", 9000, address)

print("Encode Object into JSON formatted Data using jsonpickle")
empJSON = jsonpickle.encode(employee, unpicklable=False)

print("Writing JSON Encode data into Python String")
employeeJSONData = json.dumps(empJSON, indent=4)
print(employeeJSONData)

print("Decode JSON formatted Data using jsonpickle")
EmployeeJSON = jsonpickle.decode(employeeJSONData)
print(EmployeeJSON)

# Let's load it using the load method to check if we can decode it or not.
print("Load JSON using loads() method")
employeeJSON = json.loads(EmployeeJSON)
print(employeeJSON)

输出:

Encode Object into JSON formatted Data using jsonpickle
Writing JSON Encode data into Python String
"{\"address\": {\"city\": \"Alpharetta\", \"pin\": \"30004\", \"street\": \"7258 Spring Street\"}, \"name\": \"John\", \"salary\": 9000}"

Decode JSON formatted Data using jsonpickle
{"address": {"city": "Alpharetta", "pin": "30004", "street": "7258 Spring Street"}, "name": "John", "salary": 9000}

Load JSON using loads() method
{'address': {'city': 'Alpharetta', 'pin': '30004', 'street': '7258 Spring Street'}, 'name': 'John', 'salary': 9000}

注意:

我使用unpicklable=False是因为我不想将此数据解码回 Object,如果你希望将 JSON 解码回员工对象,请使用unpicklable=True,或者直接将 JSON 数据加载到 Object 中。

此外,你可以尝试使用jsons模块使类 JSON 可序列化。

从 dict 继承以使类 JSON 可序列化

如果你不想编写自定义编码器,并且不愿意使用 jsonpickle,则可以使用此解决方案。检查此解决方案是否适合你。如果你的类不复杂,则此解决方案有效。对于更棘手的事情,你必须明确设置键。

此方法对于那些无法修改其json.dumps(obj)调用以包含自定义编码器的人很有用, 即如果你想按json.dumps(obj)原样调用,那么一个简单的解决方案是从 dict 继承。

因此,在这种情况下,你无需将调用更改为json.dumps(),我的意思是,如果你传递一个对象并且 JSON 转储发生在不同的应用程序组件或框架中,你无法控制修改json.dumps()调用,该怎么办?

让我们看看演示。

import json

class Employee(dict):
    def __init__(self, name, age, salary, address):
        dict.__init__(self, name=name, age=age, salary=salary, address=address)

class Address(dict):
    def __init__(self, city, street, pin):
        dict.__init__(self, city=city, street=street, pin=pin)

address = Address("Alpharetta", "7258 Spring Street", "30004")
employee = Employee("John", 36, 9000, address)

print("Encode into JSON formatted Data")
employeeJSON = json.dumps(employee)
print(employeeJSON)

# Let's load it using the load method to check if we can decode it or not.
print("Decode JSON formatted Data")
employeeJSONData = json.loads(employeeJSON)
print(employeeJSONData)

输出:

Encode into JSON formatted Data
{"name": "John", "age": 36, "salary": 9000, "address": {"city": "Alpharetta", "street": "7258 Spring Street", "pin": "30004"}}

Decode JSON formatted Data
{'name': 'John', 'age': 36, 'salary': 9000, 'address': {'city': 'Alpharetta', 'street': '7258 Spring Street', 'pin': '30004'}}

总结

本文介绍了4种方法使Python类JSON可序列化,你可以根据自己的实际情况或喜好,选择最合适你的一种。

您可能对以下文章也感兴趣

标签: Python  
  • IT热文
  • 站长推荐