Python中如何实现JSON到Object的序列化和反序列化?
之前写 py 关于 JSON 的序列化都是用字典来操作,比较不方便,今儿实现下 json->object 的序列化方式,发现还挺方便,分享给大家。py 菜鸟,大佬轻喷。。。使用方法如下:
核心类:
class JsonClass(object):
def to_json_string(self):
return json.dumps(self, default=lambda obj: obj.__dict__)
def from_json_string(self, json_string):
data = json.loads(json_string)
for key in self.__dict__.keys():
setattr(self, key, data[key])
使用方法:
class Task(JsonClass):
def __int__(self, id=None, name=None, timestamp=None):
self.id = id
self.name = name
self.timestamp = timestamp
if name == ‘main’:
# 序列化
task = Task(1, “a”, time.time())
print(task.to_json_string())
# 反序列化
json_string = '{"timestamp": 1560948789.5293133, "name": "a", "id": 1}'
task = Task()
task.from_json_string(json_string)
Python中如何实现JSON到Object的序列化和反序列化?
搭配 py3.6 类型标记食用更佳
在Python里处理JSON和对象转换,直接用内置的json模块配合__dict__属性或者dataclasses就能搞定。
1. 基础方法:用__dict__属性
对于简单的类,序列化时用obj.__dict__转成字典,再用json.dumps();反序列化时先用json.loads()得到字典,然后手动传给类的构造器。
import json
class User:
def __init__(self, name, age):
self.name = name
self.age = age
# 序列化:对象 -> JSON字符串
user = User("Alice", 30)
json_str = json.dumps(user.__dict__)
print(json_str) # 输出:{"name": "Alice", "age": 30}
# 反序列化:JSON字符串 -> 对象
data = json.loads(json_str)
new_user = User(data['name'], data['age'])
print(new_user.name) # 输出:Alice
2. 更优雅的方法:用dataclasses和dataclasses.asdict()
Python 3.7+的dataclasses让这活儿更干净。用@dataclass装饰器定义类,序列化用dataclasses.asdict(),反序列化用解包字典。
import json
from dataclasses import dataclass, asdict
@dataclass
class Product:
id: int
name: str
price: float
# 序列化
product = Product(1, "Laptop", 999.99)
json_str = json.dumps(asdict(product))
print(json_str) # 输出:{"id": 1, "name": "Laptop", "price": 999.99}
# 反序列化
data = json.loads(json_str)
new_product = Product(**data)
print(new_product.name) # 输出:Laptop
3. 处理复杂情况:自定义编码器/解码器
遇到日期、自定义类型等json默认不支持的,得自己写JSONEncoder和object_hook。
import json
from datetime import datetime
from dataclasses import dataclass
@dataclass
class Event:
name: str
date: datetime
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat() # 把datetime转成ISO格式字符串
return super().default(obj)
def custom_decoder(dct):
if 'date' in dct:
dct['date'] = datetime.fromisoformat(dct['date']) # 把字符串转回datetime
return dct
# 序列化
event = Event("Meeting", datetime.now())
json_str = json.dumps(asdict(event), cls=CustomEncoder)
print(json_str)
# 反序列化
data = json.loads(json_str, object_hook=custom_decoder)
new_event = Event(**data)
print(new_event.date)
简单说,普通对象用dataclasses最省事,复杂类型就自己写编码解码逻辑。
看标题还以为是自己写的解析,没想到还是调用的 api 😂
对比 字典 <–> json 的方式,是由性能优势?还是空间优势?
。。。鼓励一下
然而实质还是序列化和反序列化字典,因为字典是最接近 json 的结构的。lz 可以试一下这个,访问字典值如同访问对象属性。json.dumps 依旧有效。
https://stackoverflow.com/questions/4984647/accessing-dict-keys-like-an-attribute
尽管如此,我还是觉得 python 缺乏 struct 那样简单的构造数据的方法。
namedtuple 了解一下?
DRF 的序列化器了解一下


