【问题标题】:assert asserting when __debug__ == False当 __debug__ == False 时断言断言
【发布时间】:2015-02-19 14:05:32
【问题描述】:

我制作了一个简单的测试程序来测试使用globals()["__debug__"] = value 分配给__debug__ 的功能(__debug__ = valueSyntaxError)。它基本上试图引发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 实际上并没有检查它是否有。

【问题讨论】:

标签: python debugging assert


【解决方案1】:

您不应该更改 __debug__ 的值
正如here 下的注释所述:

注意:名称NoneFalseTrue__debug__ 不能重新分配(对它们的分配,即使作为属性名称,也会提高SyntaxError),所以它们可以被认为是“真正的”常量

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

虽然您可以通过 hack globals()["__debug__"] 更改 __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__ 的值。

【讨论】:

    猜你喜欢
    • 2013-07-26
    • 2017-01-07
    • 1970-01-01
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-03-31
    • 2021-01-08
    相关资源
    最近更新 更多