Python 3 try-except:哪种解决方案更好,为什么?

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

伙计们。 我正在尝试从外部 yaml 配置文件配置日志记录,该文件可能有也可能没有必要的选项,迫使我以几种不同的方式进行检查和故障转移。我写了两个解决方案做同样的事情,但风格不同:

更传统的“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)

和带有内部程序的“pythonic”:

    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')

它们都能满足我的需求,既短又可扩展,以防我需要更多流,但现在我想知道哪个更好,为什么?

说一个“更好”主要是个人喜好问题;如果它完成了它需要完成的任务,那么选择你喜欢的方式。也就是说,我认为应该使用第二个,原因如下:

  1. 定义 setlogstream() 既可以清楚地说明该部分代码的作用,又可以让您在以后需要时再次使用它。
  2. 使用单独的 except 案例使您的代码更具可读性和更容易理解。如果在处理第一个错误时出现另一个错误,这可能会特别有用。

总的来说,第二个更易读,你未来的自己会感谢你这样写的。