2013-02-08 13 views
9

Ho cercato di capire come caricare oggetti JSON in Python.Python json.loads non funziona

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 

Dove sto andando male?

Codice di errore (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); 

Vero Codice (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)); 

Vero Codice (Python):

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

risposta

8

I tuoi dati JSON sono racchiusi tra virgolette che lo rendono una stringa JSON, e i dati contenuti all'interno di quella stringa sono non JSON.

Stampa repr(decData) invece, si otterrà:

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

e la libreria JSON sia correttamente interpretare tale come una stringa con i contenuti letterali {'name' : 'journal2'}. Se hai rimosso le virgolette esterne, i caratteri contenuti non sono JSON validi, perché le stringhe JSON devono sempre essere racchiuse tra virgolette doppie.

Per tutto il modulo json è interessato, decData potrebbero altrettanto bene contenevano "This is not JSON" e postData sarebbe stato impostato 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) 

Fix tutto ciò sta producendo questa stringa, il vostro punto di vista è bene, è l'ingresso che è rotto.

2

Per risolvere l'errore 'Expecting nome di proprietà racchiuso tra virgolette' si può fare:

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

questo non è giusto, 'eval (data)' può ottenere il risultato corretto – WeizhongTu

+1

Questo è vero ma non si dovrebbe usare eval() penso che sia l'idea di usare il modulo json. Utilizzare eval è considerato una cattiva pratica, questa è una risposta interessante a riguardo http://stackoverflow.com/a/1832957/2289246 –

-2

Si può anche andare con eval:

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

Funziona e si restituisce un dict.

+1

A giudicare dalla risposta accettata, stai iniziando dal punto sbagliato (dovresti avere 'dati = '' '"{' name ':' journal2 '}"' '' 'per rappresentare con precisione cosa viene fornito dall'OP), il che probabilmente significa che' eval' è meno utile. –

Problemi correlati