導讀:
json是很方便的web資料格式,特別是用在ajax的資料處理上。許多Python的架構都是使用 simplejson 包來進行處理。不過最近發現我有這樣的一個需求,比如我想把一個Python的資料結構轉為javascript資料結構,也就是將python的資料結構轉為json格式,然後用在模板中使用。如,我有一個模板,其中有javascript代碼:
上面的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.csdn.net/TrackBack.aspx?PostId=2172295
本文轉自
http://blog.csdn.net/limodou/archive/2008/03/12/2172295.aspx