编写装饰器的pythonic方法是什么?

时间:2019-07-26 10:09:19

标签: python decorator python-decorators python-logging

我的目标是在程序遇到意外行为时引发SystemExit并记录错误。

我正在做类似的事情:

logger.error('Unexpected behaviour')
raise SystemExit

为了避免代码重复,我尝试在每个logger.error调用中编写一个装饰器来引发SystemExit:

error = logger.error
def error_from_logger(msg) :
    ''' Decorator for logger.error to kill the program at the call '''

    error(msg)
    raise SystemExit

logger.error = error_from_logger
del(error_from_logger)

所以我的问题是:我的装饰器是pythonic吗?如果不是,最好的pythonic编写方式是什么? (我看到人们使用@something,但我不明白它的用法。)

谢谢!

1 个答案:

答案 0 :(得分:0)

正如评论中提到的那样,您所做的并不是很好的装饰。这将是装饰:

def call_then_exit(func):
    def called_and_exited(*args, **kwargs):
        func(*args, **kwargs)
        raise SystemExit
    return called_and_exited

logger = logging.getLogger()
logger.error = call_then_exit(logger.error)  # this is the decoration

logger.error("some error has happened")  # prints the message and exists

@decorator只是在声明函数时使用的语法糖。如果您使用的是在其他地方声明的函数/方法,那么这对您来说并没有太大用处。

@call_then_exit  # this is the decoration
def say_hi():
    print('hello')

say_hi()  # prints 'hi' and exists
print('did we exit?')  # we never reach this
  

我的装饰器是pythonic吗?

可以说这不是因为补丁很难看,而且增加了意想不到的行为。更明确地说,您可以创建一个log_error_and_exit()函数或使用logging.setLoggerClass(OurLogger)注册您自己的日志记录类,还可以添加一个.fatal_error()方法。但是,我认为您的解决方案是可以的。