在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将其序列化之外,还有没有更简单的方法

在Python(2.7)中,有没有一种不使用Pickle动态生成任意JSON字符串的方法

(需要明确的是,这个查询在调用JSON.dumps()之前很久就开始构建JSON负载了。)

为什么?

假设您正在执行一个项目,该项目将涉及与多个复杂API(使用JSON)交互

将要构建并发布到API的每个JSON对象的每个实例都可能需要一个独特的层次结构(很多很多层次的对象…大量的“:”、“,”、“[]”、“{}”…你明白了)

除了实例化Python对象并通过Pickle将其序列化之外,还有没有更简单的方法来构造复杂的任意JSON字符串,而不依赖于手工/硬编码结构;比如这个[糟糕的]例子:

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似乎充满了危险。