2012-06-04 11 views
8

w Pythonie 2.7+ Mogę użyć object_pairs_hook w wbudowanym module json, aby zmienić typ dekodowanych obiektów. Czy mimo to robisz to samo dla list?Python: Zmień typ listy dla dekodowania json

Jedną z opcji jest przejście przez obiekty, które dostaję jako argumenty do haka i zastąpienie ich moim własnym typem listy, ale czy istnieje jakiś inny, mądrzejszy sposób?

Odpowiedz

6

Aby zrobić coś podobnego z listami, musisz podklasować JSONDecoder. Poniżej znajduje się prosty przykład działający jak object_pairs_hook. Wykorzystuje to czysto pytonową implementację skanowania ciągów, a nie implementację C.

import json 

class decoder(json.JSONDecoder): 

    def __init__(self, list_type=list, **kwargs): 
     json.JSONDecoder.__init__(self, **kwargs) 
     # Use the custom JSONArray 
     self.parse_array = self.JSONArray 
     # Use the python implemenation of the scanner 
     self.scan_once = json.scanner.py_make_scanner(self) 
     self.list_type=list_type 

    def JSONArray(self, s_and_end, scan_once, **kwargs): 
     values, end = json.decoder.JSONArray(s_and_end, scan_once, **kwargs) 
     return self.list_type(values), end 

s = "[1, 2, 3, 4, 3, 2]" 
print json.loads(s, cls=decoder) # [1, 2, 3, 4, 3, 2] 
print json.loads(s, cls=decoder, list_type=list) # [1, 2, 3, 4, 3, 2] 
print json.loads(s, cls=decoder, list_type=set) # set([1, 2, 3, 4]) 
print json.loads(s, cls=decoder, list_type=tuple) # set([1, 2, 3, 4, 3, 2]) 
1

Zgodnie z kodem źródłowym nie jest to możliwe: funkcja poziomu C jawnie tworzy instancję typu wbudowanego list bez korzystania z żadnych wywołań zwrotnych. To samo w bagażniku.