4

I am writing a code which tries to dig deep into the input object and find out a value lying inside that object. Here is a sample code:

def GetThatValue(inObj):
    if inObj:
       level1 = inObj.GetBelowObject()
       if level1:
           level2 = level1.GetBelowObject()
           if level2:
               level3 = level2.GetBelowObject()
               if level3:
                  return level3.GetBelowObject()
    return None

There are many situations where I end up with these "slanted if conditions". How can I avoid this? This looks dirty and also it is kind of defensive programming.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
Sadanand Upase
  • 132
  • 1
  • 15

2 Answers2

9

Using for loop:

def GetThatValue(inObj):
    for i in range(4):
        if not inObj:
            break # OR return None
        inObj = inObj.GetBelowObject()
    return inObj

UPDATE

To avoid deeply nested if statements. Check the exceptional case, and return earlier.

For example, following nested ifs:

if a:
    if b:
        return c
return d

can be transformed to flattened ifs:

if not a:
    return d
if not b:
    return d
return c
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • To add to this, if the method you're calling on each level differs, you can just use return (if not x: return none), thus avoiding unnecessarily deep nesting. – Spikes Feb 24 '14 at 07:22
  • @user1564890, If you want to avoid deeply nested `if` statement, suggestion of Spikes is a good alternative: Check exceptional condition, and return earlier. (This will make your `if` statements flattened. See http://ideone.com/oBuszQ – falsetru Feb 24 '14 at 07:29
4
try:
    return monkey.TypeWriter().Manufacturer().Shareholders().EthnicDistribution()
except AttributeError:
    return None

Try to get the thing. If it doesn't work, you know one of the levels was missing. This works particularly nicely if those GetBelowObject calls aren't actually all the same method.

user2357112
  • 260,549
  • 28
  • 431
  • 505