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')
它们都能满足我的需求,既短又可扩展,以防我需要更多流,但现在我想知道哪个更好,为什么?
说一个“更好”主要是个人喜好问题;如果它完成了它需要完成的任务,那么选择你喜欢的方式。也就是说,我认为应该使用第二个,原因如下:
- 定义
setlogstream()
既可以清楚地说明该部分代码的作用,又可以让您在以后需要时再次使用它。
- 使用单独的
except
案例使您的代码更具可读性和更容易理解。如果在处理第一个错误时出现另一个错误,这可能会特别有用。
总的来说,第二个更易读,你未来的自己会感谢你这样写的。
伙计们。 我正在尝试从外部 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')
它们都能满足我的需求,既短又可扩展,以防我需要更多流,但现在我想知道哪个更好,为什么?
说一个“更好”主要是个人喜好问题;如果它完成了它需要完成的任务,那么选择你喜欢的方式。也就是说,我认为应该使用第二个,原因如下:
- 定义
setlogstream()
既可以清楚地说明该部分代码的作用,又可以让您在以后需要时再次使用它。 - 使用单独的
except
案例使您的代码更具可读性和更容易理解。如果在处理第一个错误时出现另一个错误,这可能会特别有用。
总的来说,第二个更易读,你未来的自己会感谢你这样写的。