0

I have a dictionary that has three different kinds of key-value pairs in it. The values are one of the three shapes: A dictionary, null, or an integer, e.g.:

dic = {"range" : {"val": 1, "size": 2}, "length" : {"val": 5, "radius": 1}, "power": null, "current": 5} 

I am using a try-except block, with the dictionary value as default, and want to catch the TypeError for null and integer separately. For value null, it gives "TypeError: 'NoneType' object is not subscriptable" and for an integer, it gives "TypeError: 'int' object is not subscriptable". How do I catch these errors in different exceptions? I am looping through the keys of interest in the dictionary and an example of what I am currently doing is below, however it catches both errors as they are both TypeError:

for kw in list_of_keys: try: val_test = dic[kw]['val'] except TypeError: val_test = dic[kw] 

I would like to catch errors similar to the following:

for kw in list_of_keys: try: val_test = dic[kw]['val'] except TypeError: 'int' object is not subscriptable: val_test = dic[kw] except TypeError: 'NoneType' object is not subscriptable: val_test = "Not implemented / Not given yet" 

Thank you for your help!

3
  • 3
    There's only one kind of exception involved. You could try to match the message, but this is a case where it is not easier to ask forgiveness than to ask permission. Just look at the value of dic[kw] before trying to do anything with it. Commented Oct 20, 2021 at 19:52
  • 1
    You mean None, not null, right? Commented Oct 20, 2021 at 19:52
  • You can't. You can catch TypeError and then check what the argument says, though Commented Oct 20, 2021 at 19:54

3 Answers 3

2

Exceptions are for, well, exceptional results. Here, a None or int value seems just as valid as a dict value, so you should just look at dic[kw] before assuming it is a dict.

for kw in list_of_keys: v = dic[kw] if v is None: val_test = "Not implemented / Not given yet" else: try: val_test = v['val'] except TypeError: val_test = v 

Once you've determined if v is None or not, then you can try to index it and assume it is an int on a TypeError.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, it is a smart way of going around the issue! In my real case, I have ~80% of values as dicts and just a few as integers. I wrote null instead of None, because the data is pulled from an API to JSON and it gives value of null. Nonetheless it seems to deal with the problem.
The JSON contains the string "null", but once you decode it, you have the value None in the dict you are actually working with.
1

You can use type() keyword to check if a variable is Integer or NoneType and use try-except accordingly.

Otherwise to check if a variable is subscriptable:

from collections.abc import Iterable if isinstance(theElement, Iterable): # iterable else: # not iterable 

You can also use hasattr(myObj, '__getitem__') to check this for objects with __getitem__ method such as dict.

Comments

0

You can use .get() to check None or boolen and isinstance method to check if it is an integer.

for kw in list_of_keys: val = dic.get(kw) if not val: val = "NoneType Error" elif isinstance(val,int): val = "Integer Error" else: val=val['val'] 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.