自定义数据类型(如datetime)序列化到/从json。

jsonplus的Python项目详细描述


https://img.shields.io/pypi/v/jsonplus.svghttps://img.shields.io/pypi/l/jsonplus.svghttps://img.shields.io/pypi/wheel/jsonplus.svghttps://img.shields.io/pypi/pyversions/jsonplus.svghttps://api.travis-ci.org/randomir/jsonplus.svg?branch=master

将python类型序列化为“工作正常”的json。

忘记以下错误:

TypeError: datetime.datetime(...) is not JSON serializable

除了基本类型的(反)序列化(由simplejson)之外,jsonplus 提供对其他常用类型的exact(de-)序列化的支持,例如: tuple/namedtupleset/frozensetcomplex/decimal.Decimal/fractions.Fraction, 以及datetime/date/time/timedelta

如果类型的确切表示不是你的茶,并且你所希望的 for是使用非基本类型处理数据结构的json.dumps, 接受一路上“类型精度”的损失,就可以使用 兼容性模式(线程本地jsonplus.prefer_compat(),或 每次调用重写jsonplus.dumps(..., exact=False))。

安装

jsonplus作为python包提供。要安装它,只需键入:

$ pip install jsonplus

用法

您可以将jsonplus视为一个友好的drop in替换json/simplejson

>>>importjsonplusasjson>>>x=json.loads('{"a":1,"b":2}')>>>y=json.dumps(x,indent=4)>>>z=json.pretty(x)

示例

让我们从心爱的datetime开始。

>>>importjsonplusasjson>>>fromdatetimeimportdatetime>>>json.dumps({..."x":[4,3],..."t":datetime.now()...})'{"x":[4,3],"t":{"__class__":"datetime","__value__":"2013-09-06T23:38:55.819791"}}'>>>json.loads(_){u'x':[4,3],u't':datetime.datetime(2013,9,6,23,38,55,819791)}

类似于其他类型的datetime.*,如timedeltadatetime

>>>fromdatetimeimporttimedelta,date,time>>>print(json.pretty({"dt":timedelta(0,1234567,123),"d":date.today(),"t":datetime.now().time()})){"d":{"__class__":"date","__value__":"2013-09-22"},"dt":{"__class__":"timedelta","__value__":{"days":14,"microseconds":123,"seconds":24967}},"t":{"__class__":"time","__value__":"23:33:16.335360"}}

另外,setcomplex

>>>json.dumps([set(range(3)),1+2j])'[{"__class__":"set","__value__":[0,1,2]},{"__class__":"complex","__value__":{"real":1.0,"imag":2.0}}]'>>>json.loads(_)[set([0,1,2]),(1+2j)]

tuplenamedtuple也被保留:

>>>fromcollectionsimportnamedtuple>>>Point=namedtuple('Point',['x','y'])>>>data=json.pretty({"vect":(1,2,3),"dot":Point(3,4)})>>>print(data){"dot":{"__class__":"namedtuple","__value__":{"fields":["x","y"],"name":"Point","values":[3,4]}},"vect":{"__class__":"tuple","__value__":[1,2,3]}}>>>json.loads(data){'vect':(1,2,3),'dot':Point(x=3,y=4)}

兼容模式

完全模式下支持的所有类型在兼容性中也受支持 模式。但是,json表示方式不同。

在精确模式下,typevalueJSON Object编码 __class____value__键,在兼容模式下, 值被“舍入”为最接近的json类型

例如,tuplesetJSON Array表示,并且 namedtuple被编码为纯JSON ObjectDecimal是 表示为JSON Number,具有任意精度(如果 解码为float)。

要在exactcompatibility模式之间切换,请使用 (线程本地)函数prefer_exact()prefer_compat(),或调用 dumps(..., exact=False)

>>>importjsonplusasjson>>>json.prefer_compat()# or:>>>json.prefer(json.COMPAT)# per-instance override:>>>json.dumps(obj,exact=False)# to go back to (default) exact coding:>>>json.prefer_exact()

上面的tuple/namedtuple/datetime示例在兼容性中运行 编码模式结果:

>>>json.prefer_compat()>>>print(json.pretty({"vect":(1,2,3),"dot":Point(3,4)})){"point":{"x":3,"y":4},"vector":[1,2,3]}>>>json.dumps({"now":datetime.now()})'{"now":"2017-01-26T00:37:40.293963"}'

因此,为了能够在兼容模式下正确解码值,有些 必须向解码器提供额外的上下文。

添加用户类型

通过@jsonplus.encoder@jsonplus.decoder装饰器。

例如,要在精确模式下启用名为mytype的类型的序列化 (要添加compat模式序列化,请在decorator中附加exact=False

@jsonplus.encoder('mytype')defmytype_exact_encoder(myobj):returnmyobj.to_json()
@jsonplus.decoder('mytype')defmytype_decoder(value):returnmytype(value,reconstruct=True,...)

如果对象类的检测比简单的类名比较复杂, 如果需要使用谓词函数,只需将predicate=...添加到encoder 装饰工。例如:

@jsonplus.encoder('BaseClass',lambdaobj:isinstance(obj,BaseClass))defall_derived_classes_encoder(derived):returnderived.base_encoder()

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java如何修复尝试将用户签名到服务器主机时出现的“字符串无法转换为json对象”错误?   控制台Java:不使用新行更新命令行中的文本   java servlet接收xml数据时,出现错误   使用REST API在Bitbucket中复制或复制存储库   java如何在JavaFX中对齐一行?   java如何在活动中显示通过服务获得的数据?   返回BigDecimal作为字符串:返回int   java组织。openqa。硒。InvalidSelectorException:尝试查找元素时选择器无效   java仅在阻塞状态下通知和通知所有影响线程   java JBOSS无法启动部署   java方法的返回值能保证类型安全吗?   JavaeShadoop序列化组织。阿帕奇。hadoop。木卫一。短写失败   java如果我在同一个类上同步了两个方法,它们能同时运行吗?   不使用java数据库的spring分页实现   java如何将字符串切碎成这样的数组?