导读:
json是很方便的web数据格式,特别是用在ajax的数据处理上。许多Python的框架都是使用 simplejson 包来进行处理。不过最近发现我有这样的一个需求,比如我想把一个Python的数据结构转为javascript数据结构,也就是将python的数据结构转为json格式,然后用在模板中使用。如,我有一个模板,其中有javascript代码:
Title
<script type="text/javascript">
s = {{=data}}
</script>
上面的data我可以这样处理:
def index():
data = {'name':'limodou'};
return dict(data=simplejson.dumps(data))
这样,通过simplejson.dumps可以将一个python的数据结构转为json格式,结果为:
{"name": "limodou"}
那么,它可以正确处理基本的数据类型。使用它,要求你传入的数据应该是基本的。但是这里可能有问题:
如何处理非基本类型数据。比如从数据库中读出的日期,一般都是datetime类型,它不是基本类型,直接传入simplejson会报错
如果我不希望是"limodou",而是limodou能不能呢?为什么会有这个需求,因为在我生成的js代码中,有些可能是函数名,或执行语句,因此不是字符串,不希望自动加引号
对于第一个问题,simplejson的主页和代码中都有例子,方法就是从JSONEncoder中派生子类,然后覆盖default方法,对于特殊的类型进行处理就可以了。
对于第二个,simplejson好象没有什么支持,于是我做了扩展:
import simplejson as sj
class ComplexEncoder(sj.JSONEncoder):
def __init__(self, classes=[], **kwargs):
sj.JSONEncoder.__init__(self, **kwargs)
if not isinstance(classes, (tuple, list)):
self.classes = [classes]
else:
self.classes = list(classes)
def _iterencode_default(self, o, markers=None):
for _cls in self.classes:
if isinstance(o, _cls):
return o()
newobj = self.default(o)
return self._iterencode(newobj, markers)
class R:
def __init__(self, obj):
self.obj = obj
def __call__(self):
return self.obj
def dumps(obj, classes=R):
return sj.dumps(obj, cls=ComplexEncoder, classes=classes)
我定义了一个自已的Encoder类,然后覆盖了__init__()方法和_iterencode_default()方法。这样允许对特殊类调用类的转换方法,这样ComplexEncoder就不会对特殊类进行特殊处理了,其结果为特殊类的输出。举例:
>>>print dumps({'a':'dddddd', 'b':R('sssssss')})
{"a": "dddddd", "b": sssssss}
可以看出sssssss前后就没有双引号了。
Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=2172295
本文转自
http://blog.youkuaiyun.com/limodou/archive/2008/03/12/2172295.aspx
json是很方便的web数据格式,特别是用在ajax的数据处理上。许多Python的框架都是使用 simplejson 包来进行处理。不过最近发现我有这样的一个需求,比如我想把一个Python的数据结构转为javascript数据结构,也就是将python的数据结构转为json格式,然后用在模板中使用。如,我有一个模板,其中有javascript代码:
<script type="text/javascript">
s = {{=data}}
</script>
上面的data我可以这样处理:
def index():
data = {'name':'limodou'};
return dict(data=simplejson.dumps(data))
这样,通过simplejson.dumps可以将一个python的数据结构转为json格式,结果为:
{"name": "limodou"}
那么,它可以正确处理基本的数据类型。使用它,要求你传入的数据应该是基本的。但是这里可能有问题:
如何处理非基本类型数据。比如从数据库中读出的日期,一般都是datetime类型,它不是基本类型,直接传入simplejson会报错
如果我不希望是"limodou",而是limodou能不能呢?为什么会有这个需求,因为在我生成的js代码中,有些可能是函数名,或执行语句,因此不是字符串,不希望自动加引号
对于第一个问题,simplejson的主页和代码中都有例子,方法就是从JSONEncoder中派生子类,然后覆盖default方法,对于特殊的类型进行处理就可以了。
对于第二个,simplejson好象没有什么支持,于是我做了扩展:
import simplejson as sj
class ComplexEncoder(sj.JSONEncoder):
def __init__(self, classes=[], **kwargs):
sj.JSONEncoder.__init__(self, **kwargs)
if not isinstance(classes, (tuple, list)):
self.classes = [classes]
else:
self.classes = list(classes)
def _iterencode_default(self, o, markers=None):
for _cls in self.classes:
if isinstance(o, _cls):
return o()
newobj = self.default(o)
return self._iterencode(newobj, markers)
class R:
def __init__(self, obj):
self.obj = obj
def __call__(self):
return self.obj
def dumps(obj, classes=R):
return sj.dumps(obj, cls=ComplexEncoder, classes=classes)
我定义了一个自已的Encoder类,然后覆盖了__init__()方法和_iterencode_default()方法。这样允许对特殊类调用类的转换方法,这样ComplexEncoder就不会对特殊类进行特殊处理了,其结果为特殊类的输出。举例:
>>>print dumps({'a':'dddddd', 'b':R('sssssss')})
{"a": "dddddd", "b": sssssss}
可以看出sssssss前后就没有双引号了。
Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=2172295
本文转自
http://blog.youkuaiyun.com/limodou/archive/2008/03/12/2172295.aspx