虽然__debug__没有执行条件__debug__语句是True

时间:2013-03-09 00:29:05

标签: python debugging iis-7 python-ldap

短版

我有一段代码我正在调试,检查__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的开发服务器。

1 个答案:

答案 0 :(得分:3)

如果您重新绑定__debug__,则可能会导致与此类似的症状。

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

如果在代码上运行dis以转储字节码,您将看到if __debug__:语句被完全删除,或使用LOAD_CONST加载编译时{ {1}}不变,而debug语句使用if bool(__debug__):加载LOAD_GLOBAL的值。

当然这些保证是相同的...除非你重新绑定__debug__。在2.3左右,只写__debug__就变得非法了。在2.7和3.0中,绑定任何名为__debug__ = False属性变为非法,这意味着您不能再执行__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的代码。