Как проверить правильность строки JSON в Python?

В Python есть ли способ проверить, является ли строка действительной JSON, прежде чем пытаться ее проанализировать?

Например, работая с такими вещами, как API-интерфейс Facebook, иногда он возвращает JSON, иногда он может возвращать файл изображения.

Ответ 1

Вы можете попробовать сделать json.loads(), который выкинет ValueError, если строка, которую вы передаете, не может быть расшифрована как JSON.

В общем, философия " Pythonic" для этой ситуации называется EAFP, для упрощения запроса прощения, чем разрешения.

Ответ 2

Пример Python script возвращает логическое значение, если строка действительна json:

import json

def is_json(myjson):
  try:
    json_object = json.loads(myjson)
  except ValueError, e:
    return False
  return True

Какие принты:

print is_json("{}")                          #prints True
print is_json("{asdf}")                      #prints False
print is_json('{ "age":100}')                #prints True
print is_json("{'age':100 }")                #prints False
print is_json("{\"age\":100 }")              #prints True
print is_json('{"age":100 }')                #prints True
print is_json('{"foo":[5,6.8],"foo":"bar"}') #prints True

Преобразование строки JSON в словарь Python:

import json
mydict = json.loads('{"foo":"bar"}')
print(mydict['foo'])    #prints bar

mylist = json.loads("[5,6,7]")
print(mylist)
[5, 6, 7]

Преобразовать объект python в строку JSON:

foo = {}
foo['gummy'] = 'bear'
print(json.dumps(foo))           #prints {"gummy": "bear"}

Если вам нужен доступ к синтаксическому анализу низкого уровня, не сворачивайте свой собственный, используйте существующую библиотеку: http://www.json.org/

Отличное руководство по модулю JSON для python: https://pymotw.com/2/json/

Ответ 3

Я бы сказал, что синтаксический анализ - это единственный способ, который вы действительно можете сказать. Исключение будет вызвано функцией python json.loads() (почти наверняка), если не правильный формат. Однако в целях вашего примера вы, вероятно, можете просто проверить первые несколько символов без пробелов...

Я не знаком с JSON, который отправляет facebook, но большинство строк JSON из веб-приложений будут начинаться с открытой квадратной ([) или фигурной ({) скобки. Нет форматов изображений, которые я знаю о начале этих символов.

И наоборот, если вы знаете, какие форматы изображений могут отображаться, вы можете проверить начало строки для своих подписей для идентификации изображений и предположить, что у вас есть JSON, если это не изображение.

Еще один простой хак для идентификации графической, а не текстовой строки, в случае, если вы ищете графику, - это просто проверить не-ASCII-символы в первых двух десятках символов строки (при условии, что JSON - ASCII).

Ответ 4

Я придумал общее, интересное решение этой проблемы:

class SafeInvocator(object):
    def __init__(self, module):
        self._module = module

    def _safe(self, func):
        def inner(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except:
                return None

        return inner

    def __getattr__(self, item):
        obj = getattr(self.module, item)
        return self._safe(obj) if hasattr(obj, '__call__') else obj

и вы можете использовать его так:

safe_json = SafeInvocator(json)
text = "{'foo':'bar'}"
item = safe_json.loads(text)
if item:
    # do something

Я также разместил в своем блоге.