28

I have a string in Python, I want to know if it is valid JSON.

json.loads(mystring) will raise an error if the string is not JSON but I don't want to catch an exception.

I want something like this, but it doesn't work:

if type(mysrting) == dict:
    myStrAfterLoading = json.loads(mystring)
else:
    print "invalid json passed"

Do I have to catch that ValueError to see if my string is JSON?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
eligro
  • 785
  • 3
  • 13
  • 23
  • 8
    "… but I don't want to catch exception. I want use if, else…" Paraphrasing: "I don't want to go the easy, obvious way. I want to do it in a way that does not work." No offense intended, just joking! :) – Sven Marnach Jul 02 '12 at 13:21
  • no, I had an exception wrapper to all of the application. this should to catch real errors. if I can use if/else, I prefer it.. – eligro Jul 02 '12 at 13:25
  • 9
    I don't get that argument. You can use try/except inside try/except without any problem. – Sven Marnach Jul 02 '12 at 13:30

5 Answers5

62

The correct answer is: stop NOT wanting to catch the ValueError.

Example Python script returns a boolean if a string is valid json:

import json

def is_json(myjson):
    try:
        json_object = json.loads(myjson)
    except ValueError as 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
julienc
  • 19,087
  • 17
  • 82
  • 82
JosefAssad
  • 4,018
  • 28
  • 37
  • 2
    `TypeError: the JSON object must be str, not 'Response'` get this error – TomSawyer Sep 24 '17 at 19:15
  • fails to validate at single unicode string like u'1589649418441381790', any ideas why? – Fanglin Jan 30 '18 at 02:47
  • @lifelogger what version of Python are you using? I ran an interactive python prompt (v2.7.10) with the above code, and when I ran `print is_json(u'1589649418441381790')` it printed `True`. If you're using (I believe) v2.6 or earlier, you need the simplejson library – Doktor J May 16 '18 at 19:14
  • In case of an object of NoneType passed, it throws a TypeError – gavin May 01 '20 at 08:21
  • Imo you should never make it a normality returning from the except block/scope. I would prefer this code if possible.
       try:
            json_object = json.loads(value)
            return True
        except JSONDecodeError:
             pass
         return False
    
    – G. Juwot Feb 02 '21 at 16:50
30

To verify the string would require parsing it - so if you checked then converted it would literally take twice as long. Catching the exception is the best way. Interestingly, you can still use an if-else style expression:

try:
    json_object = json.loads(json_string)
except ValueError as e:
    pass # invalid json
else:
    pass # valid json
Goddard
  • 2,863
  • 31
  • 37
DanielB
  • 2,798
  • 1
  • 19
  • 29
10

Is there any reason you don't want to catch the exception?

Keep in mind that testing and catching an exception can be blazingly fast in Python, and is often the Pythonic way of doing things, instead of testing for type (basically, trust duck typing and react accordingly).

To put your mind a bit more at ease, take a look here: Python if vs try-except

If you're still worried about readability, add a comment to the code to explain why you're using try/except ;)

I struggled with this approach myself in the past coming from a Java background, but this is indeed the simplest way of doing this in Python... and simple is better than complex.

Community
  • 1
  • 1
pcalcao
  • 15,789
  • 1
  • 44
  • 64
  • as I said, I had exception wrapper to all of the application. I want this to catch the urgent errors so I can handle them from 1 place. use if else gives my more control on the code and to be sure i didn't except something because anoter reason.. – eligro Jul 02 '12 at 13:28
  • 2
    then do the try/except on the minimum block of code possible. You can keep the exception wrapper on your code and use try/except like it's meant to be used all the same. – pcalcao Jul 02 '12 at 13:33
  • 5
    @eligro: it sounds as if you think you can only catch exceptions in one place, or only for the whole application. This is one place where you want to catch a specific exception because it *fits the specific usecase*. – Martijn Pieters Jul 02 '12 at 13:33
  • +1 for giving reference of performance advantages of `try: except`. – Jonas Schäfer Jul 02 '12 at 13:41
0

The safest function, which also catches TypeError which happens when None type is passed

import json

def json_loads_safe(data):
    try:
        return json.loads(data)
    except (ValueError, TypeError):
        return None
pymen
  • 5,737
  • 44
  • 35
-5

why parsing when you can use types as follows:

def is_json(myjson):
    return type(myjson) == type({})

def is_json_arr(myjson):
    return type(myjson) == type([{}])
Hesham Yassin
  • 4,341
  • 2
  • 21
  • 23
  • The OP wants to test whether a string contains valid JSON. A string will never satisfy `type(myjson) == type({})`. – jwodder Jul 05 '17 at 12:58