Home > database >  Python confusion with return value in try-except-finally
Python confusion with return value in try-except-finally

Time:04-03

Here is a piece of my code:

def main():
    num = 0
    try:
        raise Exception('This is the error message.')
    except Exception:
        num  = 1
        return num
    finally:
        num  = 1

a = main()
print(a)

The returning value is 1 instead of 2, this does not make a lot of sense for me.

I thought it would return 2 since finally should execute before returning the value.

Can someone help me to understand this?

CodePudding user response:

You're running into the difference between an identifier and a value. num = 1 is creating a new int object and assigning the num identifier to point to it. It does not change the int object the identifier is already pointing to. (For small values the int objects are cached but that's an implementation detail)

You can see the difference with an operation that does mutate the object in the below code:

def y():
    l = []
    try:
        raise Exception
    except Exception:
        print("except")
        l.append(1)
        return l
    finally:
        print("finally")
        l.append(2)

print(y())
# except
# finally
# [1, 2]

CodePudding user response:

The finally is executed (this is clearly defined in the documentation), but as you return an immutable object, the modification is unseen as your returned name is now part of a different scope.

This would work as you expect with a mutable object, for instance a list:

def main():
    lst = [0]
    try:
        raise Exception('This is the error message.')
    except Exception:
        lst[0]  = 1
        return lst
    finally:
        lst[0]  = 1
a = main()
print(a)

Output: [2]

CodePudding user response:

The finally block does execute before returning the value, but the return value has already been computed.

return num evaluates num, getting 1, then the finally block starts. The finally block increments num, but the return value has already been evaluated, so it doesn't matter. At the end, the 1 computed earlier is returned.

CodePudding user response:

It's because you are returning in except block Using return word will end code execution in this function. To avoid it you could write like this:

def main():
 num = 0
 try:
    raise Exception('This is the error message.')
 except Exception:
    num  = 1
 finally:
    num  = 1
 return num

a = main()
print(a)
  • Related