2017-10-24 7 views
0

自分のロガーを初期化する2つのpythonスクリプト(test1.py、test2.py)があります。 test2.pyは、test1.pyから単一の変数をインポートします。不思議なことに、test1.pyのロガーも自動的にtest2.pyにインポートされます。私はtest2.pyを実行したときにPythonロギング - ロガーが誤って別のファイルにインポートされる

test1.py

import logging 
import logging.handlers 

LOG_FILENAME = '1.log' 
rootLogger = logging.getLogger("default") 
rootLogger.setLevel(logging.DEBUG) 

# Set up a specific logger with our desired output level 
consoleHandler = logging.StreamHandler() 
rootLogger.addHandler(consoleHandler) 

# Add the log message handler to the logger 
handler = logging.FileHandler(LOG_FILENAME) 
rootLogger.addHandler(handler) 

a = 1 
b = 2 

test2.py

import logging 
import logging.handlers 

LOG_FILENAME = '2.log' 
rootLogger = logging.getLogger("default") 
rootLogger.setLevel(logging.DEBUG) 

# Set up a specific logger with our desired output level 
consoleHandler = logging.StreamHandler() 
rootLogger.addHandler(consoleHandler) 

# Add the log message handler to the logger 
handler = logging.FileHandler(LOG_FILENAME) 
rootLogger.addHandler(handler) 


a = 3 
from test1 import b 
rootLogger.debug("a:%s",a) 
rootLogger.debug("b:%s",b) 

は今、私はtest2.pyからのみrootLoggerが呼び出されるべきであることを期待しています。もっと重要なのは、私は2.logだけが書き込まれると思った。しかし、奇妙なことに、コンソール上の出力が重複することを除けば、1.logも生成されます。

$ python test2.py 
a:3 
a:3 
b:2 
b:2 

$ cat 1.log 
a:3 
b:2 

なぜこのようなことが起こるのでしょうか、このようなシナリオを避けるためのベストプラクティスは何ですか。

更新

私は別のロガーを区別するためのgetLoggerの呼び出しを変更しました。

rootLogger = logging.getLogger(__name__) 

でも、 "1.log"ファイルが作成されますが、今回は空のままです。

rootLoggerをグローバルとして宣言するのは理想的ではありませんが、rootLoggerハンドラをすべての関数呼び出しに渡す必要があることを理解しています。

+1

モジュールから何かをインポートすると、変数が1つでも**すべて**モジュールレベルのコードが実行されることにご注意ください。 – schwobaseggl

+0

これで正確に何をしたのですか?「getLogger呼び出しを変更して、異なるロガーを区別しました。 – deimus

+0

質問自体にコードが表示されます。ここで 'rootLogger = logging.getLogger(__ name __)' – Neo

答えて

0

後でコメントしてください(感謝@schwobaseggl)、私は明らかな問題を認識しました。私が直面した問題は二つの概念を組み合わせた:あなたはそれが単一の変数であっても、モジュールから何かをインポートすると

  1. 、すべてのモジュールレベルのコードが実行されます。

  2. 同じ名前のgetLogger()を複数回呼び出すと、常に同じLoggerオブジェクトへの参照が返されます。 https://docs.python.org/2/library/logging.html

だから、基本的に、私は、スクリプトの両方で同じロガー名を使用していた、との両方からglobal module codeが実行を得ていたことから、順次、私は偶然同じロガーに二度違うのFileHandlerを追加しました。

ソリューションは、必ずif __name__ == '__main__':ブロックにロガーの初期化コードを配置します。

import logging 
import logging.handlers 

a = 1 
b = 2 

if __name__ == '__main__': 
    LOG_FILENAME = '1.log' 
    rootLogger = logging.getLogger(__name__) 
    rootLogger.setLevel(logging.DEBUG) 

# Set up a specific logger with our desired output level 
    consoleHandler = logging.StreamHandler() 
    rootLogger.addHandler(consoleHandler) 

# Add the log message handler to the logger 
    handler = logging.FileHandler(LOG_FILENAME) 
    rootLogger.addHandler(handler) 
関連する問題