在Python中(没有Pickle),可以动态构造任意JSON字符串吗?
在Python(2.7)中,有没有一种不使用Pickle动态生成任意JSON字符串的方法 (需要明确的是,这个查询在调用JSON.dumps()之前很久就开始构建JSON负载了。) 为什么? 假设您正在执行一个项目,该项目将涉及与多个复杂API(使用JSON)交互 将要构建并发布到API的每个JSON对象的每个实例都可能需要一个独特的层次结构(很多很多层次的对象…大量的“:”、“,”、“[]”、“{}”…你明白了) 除了实例化Python对象并通过Pickle将其序列化之外,还有没有更简单的方法来构造复杂的任意JSON字符串,而不依赖于手工/硬编码结构;比如这个[糟糕的]例子:在Python中(没有Pickle),可以动态构造任意JSON字符串吗?,python,json,python-2.7,pickle,Python,Json,Python 2.7,Pickle,在Python(2.7)中,有没有一种不使用Pickle动态生成任意JSON字符串的方法 (需要明确的是,这个查询在调用JSON.dumps()之前很久就开始构建JSON负载了。) 为什么? 假设您正在执行一个项目,该项目将涉及与多个复杂API(使用JSON)交互 将要构建并发布到API的每个JSON对象的每个实例都可能需要一个独特的层次结构(很多很多层次的对象…大量的“:”、“,”、“[]”、“{}”…你明白了) 除了实例化Python对象并通过Pickle将其序列化之外,还有没有更简单的方法
json_string = '{' + '"field_a": [ {' + '"id":' + id + '", "category":' + category . . . + '] }'
你的想法?建议?注释?默认JSON编码器能够从一些基本类型(例如int、str、list、dict)创建JSON,但不能处理自定义对象 例如:
json.dumps([1, 2, 3]) # this works: '[1, 2, 3]'
class A(object):
def __init__(self):
self.value1 = 1
self.value2 = {'foo': ['bar', 'baz']}
json.dumps(A()) # this fails
自定义JSON编码器
幸运的是,json允许创建自定义json编码器
自定义JSON编码器不必创建JSON。将一个对象转换成可以转换为JSON的东西是非常简单的
因此,创建一本词典就足够了
最简单的解决方案是使用适用于大多数自定义类的\uuuuuuuu dict\uuuuu
,因为\uuuuuuu dict\uuuu
包含所有成员变量的字典,字典可以通过内置编码器编码为JSON:
class DictJsonEncoder(json.JSONEncoder):
def default(self, obj):
return obj.__dict__
json.dumps(a, cls=DictJsonEncoder) # '{"value2": {"foo": ["bar", "baz"]}, "value1": 1}'
更灵活的解决方案
为了获得更大的灵活性,不要总是使用\uuuuu dict\uuuu
(但将其用作默认设置)
一种常见的模式是实现\uuu json\uu
方法,该方法执行所需的操作,并在可用时使用该方法:
class MyJsonEncoder(json.JSONEncoder):
def default(self, obj):
if hasattr(obj, '__json__'):
return obj.__json__()
else:
return super(MyJsonEncoder, self).default(obj)
然后实现默认的\uuuuu json\uuuu
方法,该方法返回\uuuu dict\uuuu
:
class JsonCapable(object):
def __json__(self):
return self.__dict__
class A(JsonCapable):
def __init__(self):
self.value1 = 1
self.value2 = {'foo': ['bar', 'baz']}
# For special needs, override __json__ here
json.dumps(a, cls=MyJsonEncoder) # '{"value2": {"foo": ["bar", "baz"]}, "value1": 1}'
或者,编码器可以使用
\uuuu json\uuu
作为备份。那么就不需要JsonCapable
类了。这个问题似乎是关于使用JSON的——为什么要谈论pickle
?这是一种完全不同的序列化技术。为什么不实例化Python对象并使用json.dumps()
进行序列化呢?对于列表/目录理解,这似乎非常可行。它还具有保证格式正确的json的额外好处。手工构建json似乎充满了危险。