2013-02-08 13 views
9

Próbowałem dowiedzieć się, jak załadować obiekty JSON w Pythonie.Python json.loads nie działa

def do_POST(self): 
    length = int(self.headers['Content-Length']) 
    decData = str(self.rfile.read(length)) 
    print decData, type(decData) 
    "{'name' : 'journal2'}" <type 'str'> 
    postData = json.loads(decData) 
    print postData, type(postData) 
    #{'name' : 'journal2'} <type 'unicode'> 
    postData = json.loads(postData) 
    print postData, type(postData) 
    # Error: Expecting property name enclosed in double quotes 

Gdzie się mylę?

Kod błędu (JScript):

var data = "{'name':'journal2'}"; 
var http_request = new XMLHttpRequest(); 
http_request.open("post", url, true); 
http_request.setRequestHeader('Content-Type', 'application/json'); 
http_request.send(data); 

prawda Code (JScript):

var data = '{"name":"journal2"}'; 
var http_request = new XMLHttpRequest(); 
http_request.open("post", url, true); 
http_request.setRequestHeader('Content-Type', 'application/json'); 
http_request.send(JSON.stringify(data)); 

prawda Code (Python):

def do_POST(self): 
    length = int(self.headers['Content-Length']) 
    decData = self.rfile.read(length) 
    postData = json.loads(decData) 
    postData = json.loads(postData) 

Odpowiedz

8

Twoje dane JSON są zawarte w dodatkowych cudzysłowach, co czyni je ciągiem JSON, i dane zawarte w tym ciągu są , a nie JSON.

Drukuj repr(decData) zamian dostaniesz:

'"{\'name\' : \'journal2\'}"' 

i biblioteka JSON jest poprawnie interpretując to jako jeden ciąg z dosłownych treści {'name' : 'journal2'}. Jeśli usunięto zewnętrzne cudzysłowy, zawarte znaki nie są poprawne JSON, ponieważ ciągi JSON muszą zawsze być ujęte w podwójne cudzysłowy.

Przez cały moduł json obawia się, decData mógłby równie dobrze zawarte "This is not JSON" i postData zostałby ustawiony u'This is not JSON'.

>>> import json 
>>> decData = '''"{'name' : 'journal2'}"''' 
>>> json.loads(decData) 
u"{'name' : 'journal2'}" 
>>> json.loads(json.loads(decData)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 326, in loads 
    return _default_decoder.decode(s) 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 366, in decode 
    obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 382, in raw_decode 
    obj, end = self.scan_once(s, idx) 
ValueError: Expecting property name: line 1 column 1 (char 1) 

Napraw wszystko, co produkuje ten ciąg, twój widok jest w porządku, to dane wejściowe są zepsute.

2

Aby obejść ten błąd 'Expecting nazwę właściwości ujęty w cudzysłów' można zrobić:

import json 
data = "{'name' : 'journal2'}" 
json.loads(json.dumps(data)) 
+4

to nie jest w porządku, 'eval (dane)' może uzyskać prawidłowy wynik – WeizhongTu

+1

To prawda, ale nie powinieneś używać eval() Myślę, że to jest pomysł użycia modułu json. Użyj eval jest uważane za złą praktykę, I to jest interesująca odpowiedź na ten temat http://stackoverflow.com/a/1832957/2289246 –

-2

Można też przejść z eval:

data = "{'name' : 'test'}" 
eval(data) 

To działa i zwraca państwu dict.

+1

Sądząc po zaakceptowanej odpowiedzi, zaczynasz od niewłaściwego punktu (potrzebujesz danych = '' '' {'name': 'journal2'} '' '' '' aby dokładnie przedstawić, co jest podane OP), co prawdopodobnie oznacza, że ​​'eval' jest mniej pomocna. –