简体   繁体   English

实现类似C的断言

[英]Implementing C-like assert

I'm trying to implement an assert function. 我正在尝试实现断言功能。 How can I get the text of the failing condition into the error message? 如何将失败情况的文本输入错误消息? If I have to parse it from the backtrace, can I portably rely on anything about the format of frames? 如果必须从回溯中解析它,是否可以随便依赖帧格式的任何内容?

AssertionError is just like any other exception in python, and assert is a simple statement that is equivalent to AssertionError就像python中的任何其他异常一样,并且assert是一个简单的语句,等效于

if __debug__:
    if not expression: raise AssertionError

or 要么

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

so you can add a second parameter to your assertion to have additional output 因此您可以在断言中添加第二个参数以获取其他输出

from sys import exc_info
from traceback import print_exception
# assertions are simply exceptions in Python
try:
    assert False, "assert was false"
except AssertionError:
    print_exception(*exc_info())

outputs 输出

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
AssertionError: assert was false

If you're sure the expression to test is secure you could do something like this: 如果您确定要测试的表达式是安全的,则可以执行以下操作:

File my_assert.py: 文件my_assert.py:

import sys

def my_assert(condition):
    caller = sys._getframe(1)
    if not eval(condition, caller.f_globals, caller.f_locals):
        raise AssertionError(repr(condition) + " on line " +
                             str(caller.f_lineno) + ' in ' +
                             caller.f_code.co_name)

File test_my_assert.py: 文件test_my_assert.py:

from my_assert import my_assert

global_var = 42

def test():
    local_var = 17
    my_assert('local_var*2 < global_var') # OK
    my_assert('local_var > global_var')

test()

Output: 输出:

Traceback (most recent call last):
  File "test_my_assert.py", line 10, in <module>
    test()
  File "test_my_assert.py", line 8, in test
    my_assert('local_var > global_var')
  File "my_assert.py", line 8, in my_assert
    caller.f_code.co_name)
AssertionError: 'local_var > global_var' on line 8 in test

My very hackish solution: 我非常骇人的解决方案:

def my_assert(condition):
    if not eval(condition):
        # error stuff

Then use it by placing the condition in quotation marks. 然后通过将条件放在引号中来使用它。 It is then a string that can be printed in the error message. 然后是可以在错误消息中打印的字符串。

Or, if you want it to actually raise an AssertionError : 或者,如果您希望它实际引发AssertionError

def my_assert(condition):
    if not eval(condition):
        raise AssertionError(condition)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM