为 Python 断言使用日志记录的“规范”方式

Posted

技术标签:

【中文标题】为 Python 断言使用日志记录的“规范”方式【英文标题】:"canonical" way to use logging for Python asserts 【发布时间】:2016-05-28 07:32:04 【问题描述】:

在以下代码中,assert 在单元测试之外使用:

import logging

if __name__ == "__main__":
    logging.basicConfig(format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO)
    logger = logging.getLogger(__name__)
    logger.info("info level")
    assert 1 == 0

打印如下:

2016-02-16 14:56:58,445 - __main__ - INFO - info level
Traceback (most recent call last):
   File "logtest.py", line 7, in <module>
    assert 1 == 0
AssertionError

使用assert 提出的AssertionError 时间戳日志记录格式的“规范”方式是什么(可能无需重写代码中的每个assert)?

有许多类似的问题被问到,主要是在单元测试上下文中处理asserts ... 谢谢

【问题讨论】:

***.com/questions/12539897/… ***.com/questions/18088879/… 澄清一下,您只想将引发的AssertionError 写入某个日志处理程序,而不是打印到stderr ***.com/questions/5191830/… ***.com/questions/1643327/… 【参考方案1】:

当您处理记录异常时,您在try except 中有可能出错的代码,然后记录异常,例如:

try:
    assert 1 == 0 
except AssertionError as err:
    logger.exception("My assert failed :( ")
    raise err

然后它会记录:

2016-02-16 15:29:43,009 - __main__ - INFO - info level
2016-02-16 15:29:43,009 - __main__ - ERROR - My assert failed :( 
Traceback (most recent call last):
  File "/home/james/PycharmProjects/scratchyard/test_time.py", line 8, in <module>
    assert 1 == 0
AssertionError

【讨论】:

这需要包装所有的断言语句。此外,当断言失败时,此代码不会退出,因此它不完全等效... 第一部分更正。第二部分,您可以通过仍然引发错误(如现在编辑所示)或致电 sys.exit() 来使其停止。 同意@gliptak:这个答案并不是很有帮助,因为它需要太多的体力劳动。应该设置一个策略来记录所有断言。 @Robert P. Goldman 我认为这不一定是真的......只要您希望将它们全部提高或全部忽略,您也可以将所有内容包装在main() 函数,然后将调用 main() 函数放在 try except AssertionError 中,并根据需要记录和/或引发所有断言,而不必单独包装每个断言......(如果你想给其中一个一种特殊的处理方法,您仍然可以单独捕获它,然后再由普通捕获物饲养和处理)

以上是关于为 Python 断言使用日志记录的“规范”方式的主要内容,如果未能解决你的问题,请参考以下文章

Java Review(三十异常处理----补充:断言日志调试)

Java Review(三十异常处理----补充:断言日志调试)

1. 编程规范和编程安全指南--python

1. 编程规范和编程安全指南--python

python基础学习日志day8-动态导入和断言

使用 Vala 进行日志记录