2012-11-23 5 views
7

オプションのロガーを関数に実装したいと思います。次のようなものがあります。コード内にオプションのロガーを実装する

def foo(arg1, arg2, arg3, logger=None): 
    logger = logger or (lambda *x: None) 

    ... 
    self.logger.debug("The connection is lost.") 

ロガーが存在する場合にロギングを実行します。さもなければ、ロガーのデバッグは何もしません。

基本的には、達成するための簡単な方法は、すべてのデバッグ文をif loggerブロックにネストすることですが、デバッグ文が多数ある場合は面倒です。

+0

あなたの状況でどのように動作するのかよく分かりませんが、ロガーが存在する場合はチェックで機能を引き継ぎ、そうでない場合は同じ名前のロガーを作成します( 'logger'と思われます) 'os.devnul'に? – RocketDonkey

+0

@iTaybこんにちは、あなたは(ダミーロガーを持って)あなたが望むもののかなり簡単な説明があります。 Pythonのロギングは通常、私が知る限りこの方法では使用されません。ロギングフィルタリングでロガーの名前を使用すると、なぜこのような回避策が必要なのか(理由は?) – tdihp

+0

@tdihp私は、提供されたロガーにその活動を記録するコード片を開発したいと思います。このコードは移植可能でなければなりません。それは(うまくいけば)多くの異なるプロジェクトで実装され、私はロギング環境を提供していません。関数のアクティビティを記録するかどうかは、開発者が決めます。私は彼にオプションを与えているだけです。 – iTayb

答えて

7

いくつかのオプション:

class DummyObject(object): 
    def __getattr__(self, name): 
     return lambda *x: None 

logger = logger or DummyObject() 

ネスティング:1つのレベルnull効果ダミーオブジェクトを作成します

logger = logger or logging.getLogger('dummy') # without configuring dummy before. 

ダミーロガー(私のお気に入り)を作成します。ブロック内のすべてのデバッグ文:

if logger: 
    logger.debug("abc") 
2

これは、loggingモジュールのためです。 How to use,Cookbook

  • self.logger属性

    あなたが本当に自分自身をロールバックしたい場合

    は、私はいくつかの選択肢を参照してください。オブジェクトの作成時または基本クラスからの継承時に設定されます。各オブジェクトには独自のロガーがあるため、インスタンスごとに選択ロギングを行うことができます。

  • 静的メソッドまたはスタンドアロンモジュールを持つロガークラス。何もしないデフォルトのメソッドを持つことができますが、ユーザは必要が生じたときにいつでも実際のハンドラと置き換えることができます。すべてのクラスは同じオブジェクトまたはモジュールにアクセスします。細分性は失われますが、セットアップ作業は少なくなります。

  • Decorators。ログに記録する各メソッドの上に@log('message', LEVEL)を置くと、メソッドが呼び出されると自動的にログが呼び出されます。かなりクリーナーで柔軟性に欠けます。

+0

それはプロジェクトには良いことです。ここで必要なのは、ロガーを引数として渡すことができるオプションのロギングを備えた非常に基本的な関数です。 – iTayb

+0

投稿したコードを使用しないのはなぜですか?ロガーのための非常に単純なクラスを作成するか、パラメータで渡されたものを出力する関数だけを作成する必要があります。 – BoppreH

+0

私はPythonにオブジェクトが存在しないにもかかわらず、それが存在しないにもかかわらず、(class1.class2.func(a、b、c)の呼び出しと何も起こらない)サブクラス化をサポートするオブジェクトがあるかどうか疑問に思いました。 – iTayb

1

私は私の答えは、単にログフィルタリングを達成する方法についてです 、何がしたいことは、フィルタリングを記録していると思います。

すでにPythonのロギングパッケージでこれが行われていますが、ロギングフィルタリングを行う方法はたくさんあります。

2つの基本的な方法があります。それは簡単に設定することができるよう

をフィルタリング

  • ログレベルのフィルタリング
  • ロガー名は、それらの両方は、ロギングの設定を使用しています。例えば

    import logging 
    
    logging.basicConfig() # easily setup a StreamHandler output 
    
    logging.getLogger("realm1").setLevel(logging.WARNING) 
    logging.getLogger("realm2").setLevel(logging.INFO) 
    
    def test(): 
        r1logger = logging.getLogger("realm1") 
        r2logger = logging.getLogger("realm2") 
        r1logger.info('r1 info') # won't print 
        r2logger.info('r2 info') # will print 
    
    if __name__ == '__main__': 
        test() 
    

    だからロギングポリシーの実行時の動的なローカルの変更を必要としない限り、慎重なログの設定と 使用のデフォルトのロガーは十分だろう。

+0

私はWARNINGログレベルを使用しないと誰が言っていましたか?しかし、私はあなたの考えを持っています。 – iTayb

5

A-何もないNullHandlerはPython 2.7以降loggingモジュールに含まれていない:

import logging  
logging.getLogger('foo').addHandler(logging.NullHandler()) 

configuring logging for a libraryのためのドキュメントを参照してください。

関連する問題