2010-09-27 83 views
31

我正在写下面的代码,在比较两个Unicode文本的多行块时,我试图产生一个像样的错误消息。这确实比较内部的方法,提出了一个说法,但默认的解释是没用的,我如何在Python AssertionError中更改消息?

我需要添加一些代码,比如下面这样:

def assert_long_strings_equal(one, other): 
    lines_one = one.splitlines() 
    lines_other = other.splitlines() 
    for line1, line2 in zip(lines_one, lines_other): 
     try: 
      my_assert_equal(line1, line2) 
     except AssertionError, error: 
      # Add some information to the printed result of error??! 
      raise 

我无法弄清楚如何改变打印错误信息在我捕捉到的断言错误中。我总是得到AssertionError: u'something' != 'something else',它只显示输出的第一行。

如何更改断言消息以打印出我想要的任何内容?

如果相关,我使用nose来运行测试。

+0

只是为了澄清,我意识到捕捉一个断言错误是奇怪的。恰巧,'my_assert_equal'很深,我不想惹它。 – 2010-09-27 21:24:26

+1

只要指出,你应该'除''不'赶上'。虽然我确信这只是一个错字:p – katrielalex 2010-09-27 21:30:46

回答

39

使用e.argse.message已被弃用。

try: 
    assert False, "Hello!" 
except AssertionError as e: 
    e.args += ('some other', 'important', 'information', 42) 
    raise 

这保留了最初的回溯。那么它的最后一部分是这样的:

AssertionError: ('Hello!', 'some other', 'important', 'information', 42) 

工作在两个的Python 2.7和Python 3

+0

这只是当我在2.7上尝试时出现类型错误。 – philologon 2016-03-31 13:50:06

+0

哪种类型的错误?我在写答案时使用了2.7。 – 2016-04-05 08:34:07

+0

@philologon我只是在Python 2.7.10和Python 3.5.1上尝试了解决方案(我的答案的确切复制粘贴),它按预期工作。我的回答已被低估,但我没有看到原因。 – 2016-04-08 09:26:29

0

创建例外时,您可以传递所需的消息。

raise AssertionError(line1 + ' != ' + line2) 

希望这会有所帮助。

+0

这不是OP的含义; 'assertionError'(通常)由'assert'语句引发。 – katrielalex 2010-09-27 21:34:42

+0

我不知道......但如果用'if'语句代替使用'assert'包装它可能是可以接受的。这样,你可以使用一个'if else'块并在一个自定义消息的AssertionError上回退。 – 2017-11-28 14:31:16

48
assert expression, info 

例如,

>>> assert False, "Oopsie" 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AssertionError: Oopsie 

docs

断言语句插入调试断言成 程序的便捷方式 :

assert_stmt ::= "assert" expression 
["," expression] 

简单形式, assert expression,相当于

if __debug__: 
    if not expression: 
     raise AssertionError 

扩展形式

assert expression1, expression2 

相当于

if __debug__: 
    if not expression1: 
     raise AssertionError(expression2) 

这些等价假定 __debug__AssertionError指的是带有那些 名称的内置变量。在目前的实现中, 的内置变量__debug__的值为 正常情况下为False 当请求优化时 (命令行选项-O)。当编译时请求优化为 时,当前的 代码生成器不会为 声明语句发出代码。请注意, 不需要在错误消息中包含 失败表达式的 源代码;它会将 显示为堆栈 跟踪的一部分。

+1

请注意,您还可以在'info'字符串表达式中嵌入换行符,以便在显示时使它们看起来不错。 – martineau 2010-09-27 23:04:34

+0

另请注意,您可以使用Python的字符串插值和更新的字符串格式化操作将附加信息添加到字符串表达式中。 – martineau 2010-09-27 23:08:20

+0

一般情况下引发异常并不是问题。这是捕捉,修改和重新提出一个表达,我问。 – 2010-09-28 05:02:08

5

您想要捕获异常,将其转换为字符串,将其与一些额外的字符串信息结合起来,并引发新的异常。

x = 3 
y = 5 
try: 
    assert(x == y) 
except AssertionError, e: 
    raise(AssertionError("Additional info. %s"%e)) 
+4

我没有看到任何发布的答案提供了如何将信息添加到例外的一般解决方案,并重新提出了原始信息和其他信息,我认为这是OP要求的。 – 2010-09-28 01:41:10

+0

罗素是正确的,这是我正在寻找的东西。 – 2010-09-28 05:01:18

+13

这会失去回溯。 – ninjagecko 2012-03-31 18:24:06

5

使用这种方法,我能够编辑消息,仍然有堆栈跟踪(+任何其他信息)可见。另外新行显示正确。

try: 
    my_assert_equal(line1, line2) 
except AssertionError as e: 
    message = e.args[0] 
    message += "\nThis appends the default message and can have newlines" 
    e.args = (message,) #wrap it up in new tuple 
    raise 
+0

这包括换行符,并且不需要复制''+ ='': ''e.args =(u“%s \ n%s”%(e.args [0],addl_message),) '' – 2016-07-25 18:44:15