e-pirate
e-pirate

Reputation: 193

Python 3 try-except: which solution is better and why?

folks. I'm trying to configure logging from an external yaml configuration file which may or may not have the necessary options forcing me to check and fail over in several different ways. I wrote two solutions doing same thing, but in different styles:

More traditional "C-like":

    try:
        if config['log']['stream'].lower() == 'console':
            handler = logging.StreamHandler()
            handler.setFormatter(logging.Formatter(fmt='scheduler: (%(levelname).1s) %(message)s'))
        elif config['log']['stream'].lower() == 'syslog':
            raise ValueError
        else:
            print('scheduler: (E) Failed to set log stream: Unknown stream: \'' + config['log']['stream'] + '\'. Failing over to syslog.', file=sys.stderr)
            raise ValueError
    except (KeyError, ValueError) as e:
        if type(e) == KeyError:
            print('scheduler: (E) Failed to set log stream: Stream is undefined. Failing over to syslog.', file=sys.stderr)
        handler = logging.handlers.SysLogHandler(facility=logging.handlers.SysLogHandler.LOG_DAEMON, address = '/dev/log')
        handler.setFormatter(logging.Formatter(fmt='scheduler[%(process)d]: (%(levelname).1s) %(message)s'))
    finally:
        log.addHandler(handler)

And "pythonic" with internal procedure:

    def setlogstream(stream):
        if stream == 'console':
            handler = logging.StreamHandler()
            handler.setFormatter(logging.Formatter(fmt='scheduler: (%(levelname).1s) %(message)s'))
        elif stream == 'syslog':
            handler = logging.handlers.SysLogHandler(facility=logging.handlers.SysLogHandler.LOG_DAEMON, address = '/dev/log')
            handler.setFormatter(logging.Formatter(fmt='scheduler[%(process)d]: (%(levelname).1s) %(message)s'))
        else:
            raise ValueError
        log.addHandler(handler)

    try:
        setlogstream(config['log']['stream'].lower())
    except KeyError:
        print('scheduler: (E) Failed to set log stream: Stream is undefined. Failing over to syslog.', file=sys.stderr)
        setlogstream('syslog')
    except ValueError:
        print('scheduler: (E) Failed to set log stream: Unknown stream: \'' + config['log']['stream'] + '\'. Failing over to syslog.', file=sys.stderr)
        setlogstream('syslog')

They both do what I need, both short, both extendible in case I need more streams, but now I wonder which one is better and why?

Upvotes: 1

Views: 67

Answers (1)

William
William

Reputation: 269

Saying one is "better" is mostly a matter of personal preference; if it accomplishes the task it needs to, then pick whichever way you prefer. That said, I think the second one should be used, and here's why:

  1. defining setlogstream() both makes it clear what that section of your code does, and allows you to use it again later, if you need to.
  2. using separate except cases makes your code more readable and easier to follow. this could be especially useful if somehow another error occurred in the handling of the first.

Overall, the second one is far more readable, and your future self will thank you for writing it that way.

Upvotes: 2

Related Questions