Scansione del json/decoder.py source code, possiamo vedere che i messaggi di errore del decoder sono costruiti utilizzando la funzione errmsg
:
def errmsg(msg, doc, pos, end=None):
# Note that this function is called from _json
lineno, colno = linecol(doc, pos)
if end is None:
fmt = '{0}: line {1} column {2} (char {3})'
return fmt.format(msg, lineno, colno, pos)
#fmt = '%s: line %d column %d (char %d)'
#return fmt % (msg, lineno, colno, pos)
endlineno, endcolno = linecol(doc, end)
fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})'
return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end)
#fmt = '%s: line %d column %d - line %d column %d (char %d - %d)'
#return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end)
Poiché si tratta di un modulo di puro-python, è facile da avvolgere questa funzione con uno personalizzato. Questo processo è noto come monkey patching:
import json
original_errmsg= json.decoder.errmsg
def our_errmsg(msg, doc, pos, end=None):
json.last_error_position= json.decoder.linecol(doc, pos)
return original_errmsg(msg, doc, pos, end)
json.decoder.errmsg= our_errmsg
try:
data = json.loads('{1:}')
except ValueError as e:
print("error at", json.last_error_position)
Ovviamente, questa soluzione non è l'ideale, dal momento che l'attuazione può cambiare in qualsiasi momento, anche se è sempre meglio che fare affidamento sul messaggio. È necessario verificare se esiste errmsg
prima dell'aggiornamento (e possibilmente se non ci sono altri argomenti o utilizzare vararg).
Questo è molto interessante, ma penso che preferirei regexare la stringa, dato che posso sempre fare qualcos'altro se la mia regex non riesce a corrispondere in una versione futura, ma questo potrebbe (mi sembra) portare ad alcuni effetti collaterali davvero orribili. Tuttavia, questo continua a rispondere alla domanda come "no" e mi consente anche di cercare tutti i formati di messaggio che potrei restituire. Grazie! –
Penso che sarebbe più bello se il parser JSON restituisse un'eccezione più qualificata che contiene questi campi. Ho aperto un [problema] (http://bugs.python.org/issue19361) per questo. –