globals()["__debug__"] = value
(__debug__ = value
是SyntaxError
)赋值给__debug__
的功能。它主要尝试引发一个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
实际上并未检查是否已更改。
您不应更改__推荐答案__的值 正如here下面的注释所述:
注意:None
、False
、True
和__debug__
不能重新赋值(为它们赋值,即使作为属性名称,也要提高SyntaxError
),因此可以将它们视为"真"常量
发生这种情况的原因是__debug__
不是在运行时计算,而是-O
命令行标志是(在编译时)计算的。另请参阅Runtime vs Compile time。
虽然您可以通过hackglobals()["__debug__"]
更改__debug__
的值,但它不执行任何操作,因为assert expression1, expression2
不会真正检查__debug__
的值。提供-O
标志会将False
赋给__debug__
,并删除所有Assert语句。也就是说,assert
语句由-O
标志删除,而不是__debug__
变量删除。
dis
中的dis()
看到这一点。使用以下代码:
import dis
dis.dis("assert False")
不带-O
标志(path ofile>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 ofile>python -O file.py
):
1 0 LOAD_CONST 0 (None)
3 RETURN_VALUE
如您所见,assert
语句基本上从代码中删除了。带有-O
标志的第0至3行与未带有标志的第12至15行相同。否它在哪里检查__debug__
的值。