关于python:decorator方法进行JSON序列化?

decorator approach to JSON serializing?

我使用JSON将数据从python发送到r(注意:我比python更熟悉r)。对于原语,json模块工作得很好。对于许多其他的python对象(例如numpy数组),您必须定义一个自定义编码器,就像在这个堆栈溢出答案中一样。但是,这需要您将编码器作为一个参数传递给json.dumps,这对于我的情况来说并不是很好。我知道还有其他一些包,比如json_tricks,它们具有更高级的JSON序列化功能,但是由于我无法控制用户拥有的Python分发,所以我不想依赖任何非默认模块将对象序列化到JSON。

我想知道是否有一种方法可以使用contextlibdecorators来定义序列化JSON对象的其他方法。理想情况下,我正在寻找一种方法,允许用户重载一些标准函数standard_wrapper,我提供这些函数来为自己的类(或从模块加载的类型)添加新方法,而不需要用户修改standard_wrapper。下面是一些伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import json

def standard_wrapper(o):
  return o


obj = [44,64,13,4,79,2,454,89,0]

json.dumps(obj)
json.dumps(standard_wrapper(obj))

import numpy as np
objnp = np.sort(obj)

json.dumps(objnp)  # FAILS

@some_decorator_to_overload_standard_wrapper
# some code

json.dumps(standard_wrapper(objnp))  # HOPEFULLY WORKS

这本质上是按类型进行的函数重载——我在Python中看到过用参数进行重载的示例,但我不知道如何按类型进行重载。

编辑我把装饰师和contextlib混在一起(我只见过用过装饰师)。


使用functools模块中的singledispatch可以很容易地按类型重载函数,如此答案所示。然而,一个可能适合我需要的简单的解决方案是创建一个函数字典,其中键对应于对象类型。

1
2
3
4
5
6
7
8
9
10
11
import numpy
func_dict = {}
a = [2,5,2,9,75,8,36,2,8]
an = numpy.sort(a)

func_dict[type(an)] = lambda x: x.tolist()
func_dict[type(a)] = lambda x: x

import json
json.dumps(func_dict[type(a)](a))
json.dumps(func_dict[type(an)](an))

通过向字典中添加另一个函数来增加对另一类型的支持。