Czy w Pythonie istnieje sposób, aby sprawdzić, czy ciąg jest prawidłowy JSON przed próbą jego przetworzenia?
Na przykład praca z takimi funkcjami, jak Facebook Graph API, czasami zwraca JSON, czasem może zwrócić plik obrazu.
Czy w Pythonie istnieje sposób, aby sprawdzić, czy ciąg jest prawidłowy JSON przed próbą jego przetworzenia?
Na przykład praca z takimi funkcjami, jak Facebook Graph API, czasami zwraca JSON, czasem może zwrócić plik obrazu.
Odpowiedzi:
Możesz spróbować zrobić json.loads(), co spowoduje wyrzucenie a, ValueErrorjeśli przekazany ciąg nie może zostać zdekodowany jako JSON.
Zasadniczo filozofia „ pytoniczna ” dla tego rodzaju sytuacji nazywa się EAFP , ponieważ łatwiej prosić o przebaczenie niż pozwolenie .
loadsw klauzuli wyjątku?
10jest prawidłową wartością liczbową JSON.
import json
def is_json(myjson):
try:
json_object = json.loads(myjson)
except ValueError as e:
return False
return True
Które wydruki:
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
Konwertuj ciąg JSON na słownik Python:
import json
mydict = json.loads('{"foo":"bar"}')
print(mydict['foo']) #prints bar
mylist = json.loads("[5,6,7]")
print(mylist)
[5, 6, 7]
Konwertuj obiekt python na ciąg JSON:
foo = {}
foo['gummy'] = 'bear'
print(json.dumps(foo)) #prints {"gummy": "bear"}
Jeśli chcesz uzyskać dostęp do analizowania niskiego poziomu, nie twórz własnych, użyj istniejącej biblioteki: http://www.json.org/
Świetny samouczek na temat modułu Python JSON: https://pymotw.com/2/json/
sudo cpan JSON::XS
echo '{"foo":[5,6.8],"foo":"bar" bar}' > myjson.json
json_xs -t none < myjson.json
Wydruki:
, or } expected while parsing object/hash, at character offset 28 (before "bar}
at /usr/local/bin/json_xs line 183, <STDIN> line 1.
json_xs jest zdolny do sprawdzania składni, parsowania, czyszczenia, kodowania, dekodowania i innych:
del json_objectraz zatwierdzić?
try. #StopCanaryAbuse
Powiedziałbym, że parsowanie to jedyny sposób, w jaki można naprawdę całkowicie powiedzieć. Wyjątkiem będzie json.loads()funkcja pytona (prawie na pewno), jeśli nie jest to poprawny format. Jednak w celach twojego przykładu możesz prawdopodobnie po prostu sprawdzić pierwszą parę znaków spoza ...
Nie znam JSON, który Facebook wysyła z powrotem, ale większość ciągów JSON z aplikacji internetowych rozpocznie się od otwartego nawiasu kwadratowego [lub kręconego {. Znane mi formaty obrazów nie zaczynają się od tych znaków.
I odwrotnie, jeśli wiesz, jakie formaty obrazu mogą się wyświetlać, możesz sprawdzić początek ciągu pod kątem ich podpisów w celu identyfikacji obrazów i założyć, że masz JSON, jeśli nie jest to obraz.
Innym prostym hackiem do identyfikacji grafiki, a nie ciągu tekstowego, w przypadku gdy szukasz grafiki, jest po prostu przetestowanie znaków spoza ASCII w pierwszych kilkudziesięciu znakach łańcucha (zakładając, że JSON to ASCII ).
Wymyśliłem ogólne, interesujące rozwiązanie tego problemu:
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
i możesz go używać w następujący sposób:
safe_json = SafeInvocator(json)
text = "{'foo':'bar'}"
item = safe_json.loads(text)
if item:
# do something
exceptklauzula może ukrywać każdy poważny wyjątek. Łapanie wyjątków musi być jak najbardziej restrykcyjne.