More elegant way to deal with multiple KeyError Exceptions
Asked Answered
F

3

5

I have the following function, which reads a dict and affects some values to local variables, which are then returned as a tuple.

The problem is that some of the desired keys may not exist in the dictionary.

So far I have this code, it does what I want but I wonder if there is a more elegant way to do it.

def getNetwork(self, search):

    data = self.get('ip',search)
    handle         = data['handle']
    name           = data['name']
    try:
        country        = data['country']     
    except KeyError:
        country = ''
    try:       
        type           = data['type']
    except KeyError:
        type = ''
    try:                
        start_addr     = data['startAddress']
    except KeyError:
        start_addr = ''
    try:                 
        end_addr       = data['endAddress']
    except KeyError:
        end_addr = '' 
    try:                  
        parent_handle  = data['parentHandle']
    except KeyError:
        parent_handle = ''   
    return (handle, name, country, type, start_addr, end_addr, parent_handle)

I'm kind of afraid by the numerous try: except: but if I put all the affectations inside a single try: except: it would stop to affect values once the first missing dict key raises an error.

Flatcar answered 4/7, 2016 at 16:24 Comment(1)
Thx for your answer both of you! I'll test that later. I really like the get() solution because it's was exactly my problem… as the doc stands : >Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.Dormancy
L
7

Just use dict.get. Each use of:

try:
    country        = data['country']     
except KeyError:
    country = ''

can be equivalently replaced with:

country = data.get('country', '')
Leanora answered 4/7, 2016 at 17:18 Comment(0)
L
1

You could instead iterate through the keys and try for each key, on success append it to a list and on failure append a " ":

ret = []
for key in {'country', 'type', 'startAddress', 'endAddress', 'parentHandle'}:
    try:
        ret.append(data[key])
    except KeyError: 
        ret.append([" "])

Then at the end of the function return a tuple:

return tuple(ret)

if that is necessary.

Lavalley answered 4/7, 2016 at 17:11 Comment(1)
You probably don't want to iterate over a set literal though, now the order of the results will vary from run to run. for key in ('country', 'type', 'startAddress', 'endAddress', 'parentHandle'): would be the efficient approach (a tuple of str literals can be built once at compile time and reused, rather than rebuilding a set or list or whatever each time the for loop begins executing).Leanora
F
0

Thx ShadowRanger, with you answer I went to the following code, which is indeed more confortable to read :

def getNetwork(self, search):
    data = self.get('ip',search)
    handle         = data.get('handle', '')
    name           = data.get('name', '')
    country        = data.get('country','')
    type           = data.get('type','')
    start_addr     = data.get('start_addr','')
    end_addr       = data.get('end_addr','')
    parent_handle  = data.get('parent_handle','')
    return (handle, name, country, type, start_addr, end_addr, parent_handle)
Flatcar answered 4/7, 2016 at 18:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.