2016-08-29 10 views
0

'%'演算子を使用してstring formatsにオプションのキーを使用することはできますか? APIをPython 2.7で使用していますので、Advanced String Formattingを使用することはできません。'%'演算子を使用する文字列形式のオプションキー?

私の問題は以下の通りです:欠落している場合、私はユーザーに空の文字列を持ちたい

>>> import logging 

>>> FORMAT = '%(asctime)-15s %(message)s %(user)s' 
>>> logging.basicConfig(format=FORMAT) 

>>> logging.warning("It works for:", extra={'user': 'me'}) 
2016-08-29 11:24:31,262 It works for: me 

>>> logging.warning("It does't work!") 
Traceback (most recent call last): 
    ... 
KeyError: 'user' 
Logged from file <input>, line 1 

。どうやってやるの?

私はdefaultdictで試したが、それは失敗します。

>>> import collections 
>>> extra = collections.defaultdict(unicode) 
>>> logging.warning("It does't work!", extra=extra) 
Traceback (most recent call last): 
    ... 
KeyError: 'user' 
Logged from file <input>, line 1 

対照的に、Jinja2で、私たちが行うことができます:ここ

>>> import jinja2 
>>> jinja2.Template('name: {{ name }}, email: {{ email }}').render(name="me") 
u'name: me, email: ' 

=>も例外、ちょうど空の文字列(のために"Eメール")。

+0

現時点では、オプションテンプレート変数についてはわかりません。しかし、あなたはこの種のようなものを試すことができます: 'logging.warning("これはうまくいきます: "、extra = {'user':ユーザー 'vars()else' '})' –

+0

@Oluwafemi Sule:this私が望むものではありません。メッセージを記録するときに、* extra *属性を使用するかどうかを選択したいと考えています。しかし、ログ形式を使用している場合、余分な属性を報告したいと思います。私の編集でJinja2の動作も見てください。 –

+0

辞書を繰り返してurの文字列を作成する – Mox

答えて

1

A)defaultdictのアプローチはうまく動作しますが、直接使用する場合に限り有効です。ドキュメントに記載されているように上記のように、ログ関数に

>>> import collections 
>>> dd=collections.defaultdict(str) 
>>> dd['k'] = 22 
>>> '%(k)s %(nn)s' % dd 
'22 ' 

B)extra引数は即ち直接ではなく、使用されています。そのため、dictの代わりにdefaultdictを使用しても差はありません。

第三のキーワード引数は、ユーザー定義の属性を持つログイベント用に作られたLogRecoed の辞書を移入するために使用され 辞書を渡すために使用することのできる余分です。


C)あなたが欠落している余分なデータの世話をするために、ログフィルタを使用することができます。

import logging 

class UserFilter: 
    def filter(self, record): 
     try: 
      record.user 
     except AttributeError: 
      record.user = '<N/A>' 
     return True 

FORMAT = '%(asctime)-15s %(message)s %(user)s' 
logging.basicConfig(format=FORMAT) 
logging.getLogger().addFilter(UserFilter()) 

logging.warning("It works for:", extra={'user': 'me'}) 

logging.warning("It doesn't work!") 
# DATE TIME It doesn't work! <N/A> 

どれでもクラスをfilter方法で結構です。それはレコードをインプレースで変更することができ、レコードを受け入れるためにはTrue、それをフィルタリングするにはFalseを返す必要があります。

関連する問題