当__debug__ == False时断言断言

时间:2015-02-19 14:05:33

标签: python debugging assert

我制作了一个简单的测试程序来测试使用__debug__globals()["__debug__"] = value__debug__ = value)分配给SyntaxError的功能。它基本上尝试引发AssertionError并在错误被提高时打印,以及是否预期错误。当我遇到__debug__更改中间程序的问题时,我这样做了。

print("__debug__ is", __debug__)
exp = ["(expected)", "(not expected)"]
if __debug__:
    exp = exp[::-1]
try:
    assert False
    print("No AssertionError", exp[0])
except AssertionError:
    print("AssertionError", exp[1])
exp = exp[::-1]
globals()["__debug__"] = not __debug__
print("__debug__ is", __debug__)
try:
    assert False
    print("No AssertionError", exp[0])
except AssertionError:
    print("AssertionError", exp[1])

从命令提示符运行时会产生意外结果,包含和不包含-O标志。

C:\Test>python assert.py
__debug__ is True
AssertionError (expected)
__debug__ is False
AssertionError (not expected)
C:\Test>python -O assert.py
__debug__ is False
No AssertionError (expected)
__debug__ is True
No AssertionError (not expected)

似乎__debug__正在发生变化,但assert实际上并没有检查它是否有。

1 个答案:

答案 0 :(得分:5)

您无意更改__debug __ 的值 正如here下的说明所述:

  

注意:无法重新分配名称NoneFalseTrue__debug__(对其进行分配,即使是属性名称) ,引发SyntaxError),因此它们可被视为“真正的”常量

发生这种情况的原因是因为__debug__在运行时评估,而-O命令行标志是(在编译时)。另见Runtime vs Compile time

虽然您可以通过黑客__debug__更改globals()["__debug__"]的值,但它不会执行任何操作,因为assert expression1, expression2没有真正检查__debug__的值。提供-O标志将False分配给__debug__并删除所有断言语句。也就是说,assert标记删除-O语句, __debug__变量。

您可以使用dis()中的dis来查看此内容。使用以下代码:

import dis
dis.dis("assert False")

没有-O标记(path\to\file>python file.py):

  1           0 LOAD_CONST               0 (False)
              3 POP_JUMP_IF_TRUE        12
              6 LOAD_GLOBAL              0 (AssertionError)
              9 RAISE_VARARGS            1
        >>   12 LOAD_CONST               1 (None)
             15 RETURN_VALUE

使用-O标记(path\to\file>python -O file.py):

  1           0 LOAD_CONST               0 (None)
              3 RETURN_VALUE

如您所见,assert语句基本上已从代码中删除。带有-O标志的第0行到第3行与第12行到第15行的相同没有。没有在哪里检查__debug__的值。