我制作了一个简单的测试程序来测试使用__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
实际上并没有检查它是否有。
答案 0 :(得分:5)
您无意更改__debug __ 的值 正如here下的说明所述:
注意:无法重新分配名称
None
,False
,True
和__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__
的值。