10

简洁版本

我有一段正在调试的代码,它检查它的值__debug__并在它为 True 时执行一些代码。

if __debug__:
  <stuff happens>

问题是“东西”永远不会发生,即使__debug__看起来是真的。

长版/详情

为了检查这一点,我正在__debug__使用以下模式在函数执行时将几个变量的值打印到文件中,最值得注意的是。(我正在使用os.open,因为open已在此模块中定义。)

try:
  myfile = os.open("test.txt", os.O_RDWR|os.O_CREAT|os.O_APPEND)
  # work + some print statements to check the value of __DEBUG__
finally:
  os.close(myfile)

我最困惑的一段代码如下所示:

os.write(myfile, "LINE %s | LDAP FUNCTION __DEBUG__: %s \n" %(sys._getframe(0).f_lineno, __debug__))
os.write(myfile, "LINE %s | LDAP FUNCTION __DEBUG__: %s \n" %(sys._getframe(0).f_lineno, type(__debug__)))
os.write(myfile, "LINE %s | LDAP FUNCTION __DEBUG__: %s \n" %(sys._getframe(0).f_lineno, bool(__debug__)))
if __debug__:
  os.write(myfile, "LINE %s | LDAP FUNCTION __DEBUG__: %s \n" %(sys._getframe(0).f_lineno, __debug__))
if bool(__debug__):
  os.write(myfile, "LINE %s | LDAP FUNCTION __DEBUG__: %s \n" %(sys._getframe(0).f_lineno, __debug__))
if True:
  os.write(myfile, "LINE %s | LDAP FUNCTION __DEBUG__: %s \n" %(sys._getframe(0).f_lineno, __debug__))
if __debug__:
  os.write(myfile, "LINE %s | LDAP FUNCTION __DEBUG__: %s \n" %(sys._getframe(0).f_lineno, __debug__))

输出文件如下所示:

LINE 82 | LDAP FUNCTION __DEBUG__: True 
LINE 83 | LDAP FUNCTION __DEBUG__: <type 'bool'> 
LINE 84 | LDAP FUNCTION __DEBUG__: True 
LINE 88 | LDAP FUNCTION __DEBUG__: True 
LINE 90 | LDAP FUNCTION __DEBUG__: True 

前 3 条语句(第 82-84 行)是我能想到的检查是否__debug__“真实”的所有方式,所有 3 条都暗示那__debug__是真实的。同样,转换__debug__为布尔值然后评估if(第 88 行)也可以按预期工作。第 90 行是一个愚蠢的完整性检查。

__debug__在可能导致这种情况的工作方式中,我有什么遗漏吗?

注意:我在处理模块中的_ldap_function_call函数时遇到的错误时发现了这一点。python-ldap我只在使用 IIS 时收到此错误 - 在 Django 的开发服务器上一切正常。

4

1 回答 1

9

如果你重新绑定__debug__,它可能会导致完全像这样的症状。

这是因为__debug__有点神奇。在模块编译期间,处理文字的相同代码也处理魔术常量...NoneTrueFalse__debug__。(例如,参见expr_constant。)

如果您dis在代码上运行以转储字节码,您会看到if __debug__:语句要么被完全删除,要么LOAD_CONST用于加载编译时常量debug,而if bool(__debug__):语句用于LOAD_GLOBAL加载__debug__.

当然,这些保证是相同的……除非你重新绑定__debug__。在 2.3 左右的某个地方,只写__debug__ = False. 在 2.7 和 3.0 中,绑定任何名为 的属性是非法的__debug__,这意味着你不能再做类似sys.modules[__name__].__debug__ = False. 但是您仍然可以这样做,例如globals()['__debug__'] = False.

无论哪种方式,您都会得到相同的效果:

if __debug__:
    print "debug"
if bool(__debug__):
    print "bool"

import sys
sys.modules[__name__].__debug__ = False

if __debug__:
    print "debug2"
if bool(__debug__):
    print "bool2"

这打印出来:

debug
bool
debug2

同样对于在运行时将其设置为 True 的代码python -O

于 2013-03-09T01:04:54.370 回答