10

短縮版

__debug__値をチェックし、 True の場合はコードを実行する、デバッグ中のコードのセクションがあります。

if __debug__:
  <stuff happens>

__debug__問題は、 True のように見えても、「何か」が決して起こらないことです。

ロングバージョン・詳細

これを確認するために、次のパターンを使用して、関数の実行時にいくつかの変数の値 (特に__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 行目) は、「真実」かどうかを確認するために考えられるすべての方法であり、3 つすべてがそれが真__debug__であることを暗示しています。__debug__同様に、ブール値としてキャスト__debug__してから評価するif(88 行目) も期待どおりに機能します。行 90 はばかげた健全性チェックです。

__debug__これを引き起こしている可能性のある方法で欠けているものはありますか?

:モジュール内の_ldap_function_call関数でエラーが発生しているときに、これを見つけました。python-ldapIIS を使用している場合にのみこのエラーが発生します。Django の開発サーバーではすべて正常に動作します。

4

1 に答える 1

9

を再バインド__debug__すると、まさにこのような症状が発生する可能性があります。

これは、__debug__やや魔法的であるためです。モジュールのコンパイル中に、リテラルを処理する同じコードで、魔法の定数...NoneTrue、も処理Falseされ__debug__ます。(たとえば、を参照してくださいexpr_constant。)

コードを実行してバイトコードをダンプすると、ステートメントが完全に削除されるか、 を使用してコンパイル時の定数をロードし、ステートメントを使用して の値をロードするdisことがわかります。if __debug__:LOAD_CONSTdebugif 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 に答える