Betere foutmelding weergeven dan “Er kan geen JSON-object worden gedecodeerd”

Python-code om gegevens uit een lang ingewikkeld JSON-bestand te laden:

with open(filename, "r") as f:
  data = json.loads(f.read())

(opmerking: de beste codeversie zou moeten zijn:

with open(filename, "r") as f:
  data = json.load(f)

maar beide vertonen hetzelfde gedrag)

Voor veel soorten JSON-fouten (ontbrekende scheidingstekens, onjuiste backslashes in tekenreeksen, enz.) wordt hiermee een aardig nuttig bericht afgedrukt met het regel- en kolomnummer waar de JSON-fout is gevonden.

Echter, voor andere soorten JSON-fouten (inclusief de klassieke “komma gebruiken op het laatste item in een lijst”, maar ook andere dingen zoals hoofdletters waar/onwaar), is de uitvoer van Python gewoon:

Traceback (most recent call last):
  File "myfile.py", line 8, in myfunction
    config = json.loads(f.read())
  File "c:\python27\lib\json\__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "c:\python27\lib\json\decoder.py", line 360, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "c:\python27\lib\json\decoder.py", line 378, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

Voor dat type ValueError, hoe zorg je ervoor dat Python je vertelt waar de fout in het JSON-bestand zit?


Antwoord 1, autoriteit 100%

Ik heb ontdekt dat de module simplejsonmeer beschrijvende fouten geeft in veel gevallen waar de ingebouwde module jsonvaag is. Bijvoorbeeld, voor het geval er een komma staat achter het laatste item in een lijst:

json.loads('[1,2,]')
....
ValueError: No JSON object could be decoded

wat niet erg beschrijvend is. Dezelfde bewerking met simplejson:

simplejson.loads('[1,2,]')
...
simplejson.decoder.JSONDecodeError: Expecting object: line 1 column 5 (char 5)

Veel beter! Hetzelfde geldt voor andere veelvoorkomende fouten, zoals hoofdletters True.


Antwoord 2, autoriteit 8%

Je kunt Python niet laten vertellen waar de JSON onjuist is. U moet ergens online een linter gebruiken, zoals dit

Hiermee wordt een fout weergegeven in de JSON die u probeert te decoderen.


Antwoord 3, autoriteit 4%

U kunt de rson-bibliotheek proberen die u hier vindt: http://code.google.com/p/ rson/. Ik heb het ook op PYPI: https://pypi.python.org/pypi/rson/0.9zodat je easy_install of pip kunt gebruiken om het te krijgen.

voor het voorbeeld gegeven door tom:

>>> rson.loads('[1,2,]')
...
rson.base.tokenizer.RSONDecodeError: Unexpected trailing comma: line 1, column 6, text ']'

RSON is ontworpen als een superset van JSON, zodat het JSON-bestanden kan ontleden. Het heeft ook een alternatieve syntaxis die veelfijner is voor mensen om naar te kijken en te bewerken. Ik gebruik het nogal wat voor invoerbestanden.

Wat betreft het hoofdlettergebruik van booleaanse waarden: het lijkt erop dat rson booleans met een onjuist hoofdletter als tekenreeksen leest.

>>> rson.loads('[true,False]')
[True, u'False']

Antwoord 4, autoriteit 2%

Ik had een soortgelijk probleem en het was te wijten aan enkele aanhalingstekens. De JSON-standaard(http://json.org) spreekt alleen over het gebruik van dubbele aanhalingstekens, zodat het moet zijn dat de python jsonbibliotheek alleen dubbele aanhalingstekens ondersteunt.


Antwoord 5, autoriteit 2%

Voor mijn specifieke versie van dit probleem ging ik door en doorzocht de functiedeclaratie van load_json_file(path)in het bestand packaging.pyen smokkelde vervolgens een printregel erin:

def load_json_file(path):
    data = open(path, 'r').read()
    print data
    try:
        return Bunch(json.loads(data))
    except ValueError, e:
        raise MalformedJsonFileError('%s when reading "%s"' % (str(e),
                                                               path))

Op die manier zou het de inhoud van het json-bestand afdrukken voordat het de try-catch invoerde, en op die manier kon ik – zelfs met mijn nauwelijks bestaande Python-kennis – snel achterhalen waarom mijn configuratie het json-bestand niet kon lezen .
(Het was omdat ik mijn teksteditor had ingesteld om een UTF-8 stuklijst te schrijven … stom)

Ik vermeld dit alleen maar omdat, hoewel dit misschien geen goed antwoord is op het specifieke probleem van de OP, dit een vrij snelle methode was om de bron van een zeer onderdrukkende bug te achterhalen. En ik wed dat veel mensen dit artikel zullen tegenkomen die op zoek zijn naar een uitgebreidere oplossing voor een MalformedJsonFileError: No JSON object could be decoded when reading …. Dus dat zou hen kunnen helpen.


Antwoord 6, autoriteit 2%

Wat mij betreft, mijn json-bestand is erg groot, bij gebruik van gewone jsonin python krijgt het de bovenstaande foutmelding.

Na installatie simplejsonvan sudo pip install simplejson.

En toen loste ik het op.

import json
import simplejson
def test_parse_json():
    f_path = '/home/hello/_data.json'
    with open(f_path) as f:
        # j_data = json.load(f)      # ValueError: No JSON object could be decoded
        j_data = simplejson.load(f)  # right
    lst_img = j_data['images']['image']
    print lst_img[0]
if __name__ == '__main__':
    test_parse_json()

7

Raak gewoon hetzelfde probleem en in mijn geval was het probleem gerelateerd aan BOM(byte-ordermarkering) aan het begin van het bestand.

json.toolzou weigeren zelfs leeg bestand (gewoon krullende beugels) te verwerken totdat ik het UTF-bom-markering heb verwijderd.

Wat ik heb gedaan is:

  • opende mijn JSON-bestand met vim,
  • verwijderde byte bestelteken (set nobomb)
  • Bestand opslaan

Dit is het probleem opgelost met JSON.TOOL. Ik hoop dat dit helpt!


8

Wanneer uw bestand is aangemaakt. In plaats van een bestand te maken met inhoud is leeg. Vervang door:

json.dump({}, file)

Antwoord 9

Je zou cjsonkunnen gebruiken, die beweert tot 250 keer sneller te zijn dan pure -python-implementaties, aangezien je “een lang gecompliceerd JSON-bestand” hebt en je het waarschijnlijk meerdere keren moet uitvoeren (decoders falen en rapporteren alleen de eerste fout die ze tegenkomen).

Other episodes