自定义数据类型(如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如何创建一个透明的Android应用程序,它将占据整个屏幕(位于状态/导航栏上方)?   Spark Java编码器。bean无法转换为Scala定义的类   java无法在可执行jar中加载资源   java如何避免Checkstyle的FinalClass模块在存在从基继承的内部类时抱怨?   文件Netbeans java小程序项目屏幕弹出   java解析增量特性的增量不会超过值1   java从另一个类创建一个对话框,该类在Android中有自己的线程   java如何在绘制线条时向JPanel添加背景网格?   方法来确定路径字符串是本地计算机还是Java的远程计算机   批处理文件在java中如何在执行命令之前设置目录   需要关于Java8流逻辑的帮助吗   java Guice注入和请求工厂:扩展ServiceLayerCorator