我做了一个简单的测试程序来测试分配给 __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
实际上并没有检查它是否改变了。
最佳答案
您不应该更改 __debug__ 的值
正如here下的注释状态:
Note: The names
None
,False
,True
and__debug__
cannot be reassigned (assignments to them, even as an attribute name, raiseSyntaxError
), so they can be considered “true” constants
发生这种情况的原因是因为 __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__
的值。
关于python - 断言 __debug__ == False 时断言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28608385/