如何在python脚本中捕获断言

时间:2016-11-03 23:58:31

标签: python python-2.7 assert

在Python2.7中有什么办法,我们可以捕获并记录一般python脚本中的断言语句,尽管assert是True或False 假设我在代码中断言以下行:

assert len(lst) ==4

因此,任何方式都可以记录传递的语句,在哪一行,它是真还是假。我不想使用包装函数,在python中寻找内置的东西。

注意:我想要实现的是,假设我有遗留代码有1000个断言语句,而不更改代码,我应该能够记录执行哪个断言语句以及输出是什么,它是否可以在python中实现2.7。

4 个答案:

答案 0 :(得分:3)

try:
    assert len(lst) == 4    
    print "True"
except AssertionError as e:
    print "False"

答案 1 :(得分:2)

是的,您可以定义自定义excepthook以记录一些额外信息:

import sys
import logging
def excepthook(*args):
  logging.getLogger().error('Uncaught exception:', exc_info=args)

sys.excepthook = excepthook

assert 1==2

编辑:哎呀我忘了你想记录即使它是真的:)哦,如果它通知你或其他人,我会留下一点......

答案 2 :(得分:1)

这是我可以实现的壁橱,因为在Python2.7中似乎不可能。我创建了一个包装函数。

import inspect

def assertit(condition,message):
    # The caller method
    (frame, filename, line_number,function_name, lines, index) = inspect.getouterframes(inspect.currentframe())[1]


    detailed_message=" => {message} [  {filename} : {line_number}]".format(message=message,line_number=line_number,
                                                                         filename=filename)

    if condition:
        print "True  %s"%detailed_message
        return
    raise AssertionError("False: %s"%detailed_message)
assertit(1==1,"Check if 1 equal 1")
assertit(1==2,"Check if 1 equal 2")

### HERE IS THE OUTPUT
True   => Check if 1 equal 1 [  test_cases.py : 20]
Traceback (most recent call last):
  File "test_cases.py", line 21, in <module>
    assertit(1==2,"Check if 1 equal 2")
  File "test_cases.py", line 19, in assertit
    raise AssertionError("False: %s"%detailed_message)
AssertionError: False:  => Check if 1 equal 2 [  test_cases.py : 21]

答案 3 :(得分:0)

这是一个概念证明。所以请downvote,否则我会删除它... 我们的想法是在执行时用assert语句替换print语句。

import ast
import inspect

from your_module import main

def my_assert(test_result, msg):
    assert test_result, msg
    # if test_result is True, just print the msg
    return "assert: {}, {}".format(test_result, msg)

class Transformer(ast.NodeTransformer):
    def visit_Assert(self, node):
        f = ast.Name(id='my_assert', ctx=ast.Load())
        c = ast.Call(func=f, args=[node.test, node.msg], keywords=[])
        p = ast.Print(values=[c], nl=True)

        # set line#, column offset same as the original assert statement
        f.lineno = c.lineno = p.lineno = node.lineno
        f.col_offset =c.col_offset = p.col_offset = node.col_offset

        return p


def replace_assert_with_print(func):
    source = inspect.getsource(func)
    ast_tree = ast.parse(source)
    Transformer().visit(ast_tree)
    return compile(ast_tree, filename="<ast>", mode="exec")

if __name__ == '__main__':
    exec(replace_assert_with_print(main))
    main(4)

这是your_module.py

def main(x):
    assert x == 4, "hey {} is not 4".format(x)
    return x