【问题标题】:What's Python JSON serializable?什么是 Python JSON 可序列化?
【发布时间】:2021-12-29 00:04:37
【问题描述】:

我有两种方法可以用json.dumps()表示Python对象

第一:

person = {
"name": "John",
"age": 30,
"city": "New York"
}

第二:

class Person:
   def _init_(self, name, age, city):
      self.name = name
      self.age = age
      self.city = city

person = Person("John", 30, "New York")

然后我尝试p1 = json.dumps(person),第二种方式是it's not JSON serializable

所以基本上对于 Python,json.dumps 只适用于像 dict 对象这样的内置对象?

【问题讨论】:

  • 是的;默认情况下,json 模块只知道如何序列化内置类型。查看json.JSONEncoder 了解如何序列化您自己的类的实例。

标签: python json serialization


【解决方案1】:

如果您询问的是普通 Python,可以通过这种方式进行序列化:

import json


class Person:
   def __init__(self, name, age, city):
      self.name = name
      self.age = age
      self.city = city

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


person = Person("John", 30, "New York")
print(person.to_json())

所以我们只是使用__dict__ 属性将对象转换为字典。

但如果您需要更复杂的东西,您可能需要DRF(Django REST 框架)或pydantic。一个如何使用 DRF 完成的示例:

from rest_framework import serializers
from rest_framework.serializers import Serializer


class Person:
   def __init__(self, name, age, city):
      self.name = name
      self.age = age
      self.city = city


class PersonSerializer(Serializer):
    name = serializers.CharField()
    age = serializers.IntegerField()
    city = serializers.CharField()

    def create(self, validated_data):
        return Person(**validated_data)


person = Person("John", 30, "New York")
print(PersonSerializer(person).data)

这样你可以更好地控制它。见docs

【讨论】:

    【解决方案2】:

    是的,json 模块只知道如何序列化某些内置类型。使用具有“字段”的类的一种简单方法是 dataclasses 模块。

    例子:

    from dataclasses import dataclass, asdict
    import json
    
    @dataclass
    class Person:
        name: str
        age: int
        city: str
    
    person = Person("John", 30, "New York")
    print(json.dumps(asdict(person)))
    

    asdict() 函数将数据类实例转换为dictjson 可以对其进行序列化。

    【讨论】:

      【解决方案3】:

      在 Python 3.6+ 中,您可以在 Python 中使用 dataclassesasdict 辅助函数将数据类实例转换为 Python dict 对象。

      注意:对于 3.6,您需要为 dataclasses 模块提供一个 backport,因为它从 3.7 开始才成为 Python 的内置函数。

      import json
      from dataclasses import dataclass, asdict
      
      
      @dataclass
      class Person:
          name: str
          age: int
          city: str
      
      
      person = Person("John", 30, "New York")
      person_dict = asdict(person)
      
      json_string = json.dumps(person_dict, indent=2)
      
      print(json_string)
      

      输出:

      {
        "name": "John",
        "age": 30,
        "city": "New York"
      }
      

      如果您有一个更复杂的用例,或者最终需要(反)序列化嵌套数据类模型,我会查看一个外部库,例如 dataclass-wizard,它特别支持这种用例。

      【讨论】:

        猜你喜欢
        • 2011-01-15
        • 2018-03-05
        • 2011-03-20
        • 1970-01-01
        • 2016-01-22
        • 2010-11-21
        • 2011-03-26
        • 2016-12-02
        相关资源
        最近更新 更多