-2

In a very well written and awesome book by Robert Smallshire and Austin Bingham there is the following code:

def convert(s):
    """Convert a string to an integer."""
    try:
        return int(s)
    except (ValueError, TypeError) as e:
        print("Conversion error: {}".format(str(e)), file=sys.stderr)
        raise

after that, the author has included the following string_log function

def string_log(s):
    v = convert(s)
    return log(v)

and the output of string_log('ouch') is as follow

I am not able to understand what raise statement exactly works?

Also, the author says that the code where the first function outputs negative error code of -1 in case of ValueError and TypeError i.e the first function would be as follow

import sys

def convert(s):
    """Convert a string to an integer."""
    try:
        return int(s)
    except (ValueError, TypeError) as e:
        print("Conversion error: {}".format(str(e)), file=sys.stderr)
        return -1

and than if we run the following (without any change made string_log()) is string_log('cat')

Is unpythonic but why?

Tim
  • 2,510
  • 1
  • 22
  • 26

1 Answers1

1

If convert returns -1 on an error, then you have to explicitly check for that to avoid having string_log return -1 as well. Just like string_log is expecting convert to return a valid string, so might the caller. Letting -1 propagate can go undetected for a long time, and once an error does occur, it's not clear what the source of the error was.

With an exception, string_log doesn't return if it doesn't catch the exception; the exception continues up the call stack until it is caught, or the interpreter exits with a traceback. That traceback will show exactly where the exception originates.


raise with no argument simply raises the most recent exception, without having to write something like

except (ValueError, TypeError) as e:
    print("Conversion error: {}".format(str(e)), file=sys.stderr)
    raise e

Here, you are using e in the call to print anyway, but if you didn't, you could write

except (ValueError, TypeError):
    print("Something bad happened!")
    raise

without having to bind the exception to an explicit name.

chepner
  • 497,756
  • 71
  • 530
  • 681