这是一个相当无用的断言错误;它不会告诉所涉及的表达式的值(假设使用的常量实际上是变量名):
$ python -c "assert 6-(3*2)"
[...]
AssertionError
Python 中是否有更好、更奇特的 assert
实现?它不得在执行过程中引入额外的开销(除非断言失败)..并且如果使用 -O
标志,则必须关闭。
编辑:我知道断言的第二个参数是字符串。我不想写一个..,因为它被编码在正在断言的表达式中。 DRY(不要重复自己)。
This is a rather useless assertion error; it does not tell the values of the expression involved (assume constants used are actually variable names):
$ python -c "assert 6-(3*2)"
[...]
AssertionError
Is there a better assert
implementation in Python that is more fancy? It must not introduce additional overhead over execution (except when assert fails) .. and must turn off if -O
flag is used.
Edit: I know about assert's second argument as a string. I don't want to write one .. as that is encoded in the expression that is being asserted. DRY (Don't Repeat Yourself).
发布评论
评论(7)
将您的函数安装为
sys.excepthook
- 请参阅文档。如果第二个参数是AssertionError
,你的函数可以内省你内心的内容;特别是,通过第三个参数,即回溯,它可以获取断言失败的帧和确切位置,通过源代码或字节码获取失败的异常,所有相关变量的值等。 Module inspect 有帮助。完全通用地做到这一点是一项相当大的工作,但是根据您在编写
assert
时愿意接受的限制,它可以大大减轻(例如,将它们限制为仅本地或与涉及闭包的非局部变量相比,全局变量使内省更加容易,等等)。Install your of function as
sys.excepthook
-- see the docs. Your function, if the second argument isAssertionError
, can introspect to your heart's contents; in particular, through the third argument, the traceback, it can get the frame and exact spot in which the assert failed, getting the failing exception through the source or bytecode, the value of all relevant variables, etc. Module inspect helps.Doing it in full generality is quite a piece of work, but depending on what constraints you're willing to accept in how you write your
assert
s it can be lightened substantially (e.g. restricting them to only local or global variables makes introspection easier than if nonlocal variables of a closure could be involved, and so forth).您可以将消息附加到
断言
:该消息也可以动态构建:
请参阅Python 文档中的
assert
声明 了解更多信息。You can attach a message to an
assert
:The message can also be built dynamically:
See The
assert
statement in the Python documentation for more information.正如 @Mark Rushakoff 所说
鼻子
可以评估失败的断言。它也适用于标准assert
。nosetests
' 帮助:示例:
As @Mark Rushakoff said
nose
can evaluate failed asserts. It works on the standardassert
too.nosetests
' help:Example:
nose 测试套件将内省应用于断言。
但是,AFAICT,您必须调用他们的断言来进行内省:
导致
注意那里的 AssertionError 。当我的行只是
assert 6 == 5+2
时,我会得到:另外,我不确定他们的断言是否被
-O
跳过,但是那将是一个非常快速的检查。The nose testing suite applies introspection to asserts.
However, AFAICT, you have to call their asserts to get the introspection:
results in
Notice the AssertionError there. When my line was just
assert 6 == 5+2
, I would get:Also, I'm not sure offhand if their asserts are skipped with
-O
, but that would be a very quick check.我编写了 sys.excepthook 的替代代码(任何未处理的异常都会调用它),它比标准的更奇特。它将分析发生异常的行并打印该行中引用的所有变量(它不会打印所有局部变量,因为这可能会产生太多噪音 - 而且,也许重要的 var 是全局变量等)。
我将其命名为 py_better_exchook(完美的名称),它位于此处。
示例文件:
输出:
还有一些其他替代方案:(
I coded a replacement for
sys.excepthook
(which is called for any unhandled exception) which is a bit more fancy than the standard one. It will analyze the line where the exception occured and print all variables which are referred to in this line (it does not print all local variables because that might be too much noise - also, maybe the important var is global or so).I called it py_better_exchook (perfect name) and it's here.
Example file:
Output:
There are a few other alternatives:
from IPython.core import ultratb; sys.excepthook = ultratb.VerboseTB()
.听起来您真正想做的是在断言之前设置一个调试器断点,并根据您喜欢的方式从您最喜欢的调试器进行检查。
It sounds like what you really want to do is to set up a debugger breakpoint just before the
assert
and inspect from your favorite debugger as much as you like.向断言添加一条消息,如果断言失败,将显示该消息:
我能想到的自动提供此消息的唯一方法是将断言包含在过程调用中,然后检查堆栈以获取该断言的源代码线。不幸的是,额外的调用会给测试带来开销,并且不会用
-O
禁用。Add a message to your assertion, which will be displayed if the assertion fails:
The only way I can think of to provide this automatically would be to contain the assertion in a procedure call, and then inspect the stack to get the source code for that line. The additional call would, unfortunately, introduce overhead into the test and would not be disabled with
-O
.