9

私のアプリケーションではpython.logging、ロギングに使用しています。

ログレベルをインタラクティブに制御したいので、ユーザーが「エラー」、「警告」、「情報」などを選択できるコンボボックス ハットを作成しました。

私が本当に気に入らないのは、現在、コンボボックスの値がハードコードされていることです。代わりに、Ii はすべての「名前付き」ログレベルのリストを取得したいと考えています (たとえば、システムの既定値の両方と、 を介して追加されたものも含まれますが、「 Level 42logging.addLevelName 」のような偽の生成されたログレベルは含まれません) 。

私がこれまで思いついた最善の方法は、logging._levelNames辞書を使用することです。

しかし、これはプライベートメンバーのようで、直接アクセスするのはどういうわけか悪い予感がします。

だから私の質問は、Pythonで現在定義されているすべての「名前付き」ログレベルをリストする適切な方法は何ですか.

4

7 に答える 7

6

あなたは値を読んでいるだけlogging._levelNamesなので、私には適切な解決策に見えます。logging.addLevelNameただし、新しい値を設定するために続けてください。

于 2013-09-17T09:38:22.533 に答える
3

やりたいことを実行するための特定の機能はありませんが、必要なものはすべてlogging._levelNames.

addLevelNameたとえば、定義を見てみましょう。

def addLevelName(level, levelName):
    """
    Associate 'levelName' with 'level'.

    This is used when converting levels to text during message formatting.
    """
    _acquireLock()
    try:    #unlikely to cause an exception, but you never know...
        _levelNames[level] = levelName
        _levelNames[levelName] = level
    finally:
        _releaseLock()

したがって、 aは次のgetLevelNames()ように実装できます。

import logging
def getLevelNames():
    for k, v in sorted(logging._levelNames.iteritems()):
        if isinstance(v, basestring):
            yield v, k

import pprint
pprint.pprint(list(getLevelNames()))

出力例:

[('NOTSET', 0),
 ('DEBUG', 10),
 ('INFO', 20),
 ('WARNING', 30),
 ('ERROR', 40),
 ('CRITICAL', 50)]
于 2013-09-17T09:35:56.637 に答える
0

私も、このモジュールが public attr やメソッドを提供していないことにがっかりしています。Python 2 および 3 で機能する簡潔なソリューションを次に示します。

import logging
LOG_LEVEL_NAMES = [logging.getLevelName(v) for v in
                   sorted(getattr(logging, '_levelToName', None)
                          or logging._levelNames)
                   if getattr(v, "real", 0)]

内訳: モジュール名 ( logging) は変更されていないため、可能であれば、を使用して Python 3 の値を取得することで、py2/3 互換性をtry/except回避できます。ImportErrorgetattr(logging, '_levelToName', None)

Python 2 では を取得しますがlogging._levelNames、これは少し異なります。これには int->string と string->int の両方のマッピングがあるためgetattr(v, "real", 0)、フィルターがすべての文字列値を 0 として扱うようにするために使用します。またlogging.NOTSET、この方法で破棄します。

次に、値を並べ替えてマップlogging.getLevelNameし、順序付けされた名前のリストに戻します。

于 2018-04-09T01:00:51.053 に答える