2012-10-11 3 views
18

のフォーマットは、私は私のPythonのバージョンがパイソン:ログはTypeError:すべての引数が文字列中に変換されません。ここ

>>> import logging 
>>> logging.getLogger().setLevel(logging.INFO) 
>>> from datetime import date 
>>> date = date.today() 
>>> logging.info('date={}', date) 
Traceback (most recent call last): 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 846, in emit 
    msg = self.format(record) 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 723, in format 
    return fmt.format(record) 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 464, in format 
    record.message = record.getMessage() 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 328, in getMessage 
    msg = msg % self.args 
TypeError: not all arguments converted during string formatting 
Logged from file <stdin>, line 1 
>>> 

をやっているものですが、私はそれを動作させるにはどうすればよい

$ python --version 
Python 2.7.3 

のですか?

答えて

10

あなたは行うことができ、自分自身のフォーマット:メッセージ場合にのみ実行されるように書式設定を引き起こすロギングモジュールを使用している間

logging.info('date={}'.format(date)) 

マルタインピータースが指摘したように、これは常に、文字列フォーマットを実行しますが実際に記録されます。

+15

は、書式設定を自分で行うことによって、あなたはロギングモジュールをさせることにより、提供速度の利点を失うことを知っていたメッセージがある場合にのみ、*あなたのためにそれを行う:それからちょうどログクラスを設定し

import logging class LogRecord(logging.LogRecord): def getMessage(self): msg = self.msg if self.args: if isinstance(self.args, dict): msg = msg.format(**self.args) else: msg = msg.format(*self.args) return msg class Logger(logging.Logger): def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None): rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func) if extra is not None: for key in extra: rv.__dict__[key] = extra[key] return rv 

実際に記録*。言い換えれば、 'debug()'ハンドラを使用しているのにロギングレベルがDEBUGレベルを除外している場合、文字列フォーマット操作のペナルティは発生しません。多くのデバッグメッセージがある場合は、速度差が大きくなる可能性があります。 –

32

ロギングモジュールを使用しているときに新しいスタイルの書式を使用することはできません。 {}の代わりに%sを使用してください。

logging.info('date=%s', date) 

ロギングモジュールは、ログ文字列をフォーマットする古いスタイル%演算子を使用しています。詳細については、debug methodを参照してください。

あなたは本当に、str.format()文字列フォーマットを使用して書式設定を適用するカスタムオブジェクトを使用することを検討したい場合は「後半」、実際に文字列に変換するとき:

class BraceMessage(object): 
    def __init__(self, fmt, *args, **kwargs): 
     self.fmt = fmt 
     self.args = args 
     self.kwargs = kwargs 

    def __str__(self): 
     return self.fmt.format(*self.args, **self.kwargs) 

__ = BraceMessage 

logging.info(__('date={}', date)) 

これはアプローチPython 3 logging module documentation proposesあり、そしてそれが起こりますPython 2でも動作します。

6

Martijnの回答は正しいですが、ロギングで新しいスタイルの書式を使用する場合は、Loggerをサブクラス化することで達成できます。

logging.setLoggerClass(Logger) 
+0

あるいは(少なくともPython 3.5では) 'logging.setLogRecordFactory(LogRecord)'でLogRecordだけを使用します。 –

関連する問題