5

複雑なネストされた dict オブジェクトがあります。

value = { 
    'a': '100', 
    bits: {
        1: 'alpha', 
        2: 'beta', 
        3: ['31', '32', 901]
    }
}

テンプレートを使用して「安全に」フォーマットする必要があります。キーが見つからない場合は、{}プレースホルダーを静かに無視してください。キーが存在しない可能性があり、KeyErrors を発生させたくありません。問題は、string.Template が str.format と同じ機能を処理できないことです。私が使用した str.format は次のようなものです。

"a=${a}, b1={bits[1]}, b31={bits[3]}, b9={bits[9]}".format(**value)

出力は次のようになります。

"a=100, b1=alpha, b31=(31, 32, 901), b9="

派手なループや if/else 条件は必要ありません。サブ辞書付きの単純なフォーマット。

私が持っているオプションは何ですか?私は可能な限りビルトインを使用するか、非常に小さなライブラリを使用することを好みます。

これは Web アプリではないため、可能であれば、このためだけに jinja2 のようなライブラリをロードすることは避けたいと考えています。

4

2 に答える 2

3

独自のフォーマッタを作成します。

In [1]: from string import Formatter

In [2]: value = { 
   ...:     'a': '100', 
   ...:     'bits': {
   ...:         1: 'alpha', 
   ...:         2: 'beta', 
   ...:         3: ['31', '32', 901]}}

In [3]: class YourFormatter(Formatter):
   ...:     def get_value(self, field_name, args, kwargs):
   ...:         return kwargs.get(field_name, '')
   ...: 
   ...:     def get_field(self, field_name, args, kwargs):
   ...:         first, rest = field_name._formatter_field_name_split() 
   ...:         obj = self.get_value(first, args, kwargs) 
   ...:         
   ...:         for is_attr, i in rest:
   ...:             if is_attr:
   ...:                 obj = getattr(obj, i)
   ...:             else:
   ...:                 obj = obj.get(i, '')
   ...:         return obj, first
   ...:     


In [4]: fmt = YourFormatter()

In [5]: fmt.format("a={a}, b1={bits[1]}, b31={bits[3]}, b9={bits[9]}", **value)
Out[5]: "a=100, b1=alpha, b31=['31', '32', 901], b9="

Python 3 の場合、追加する必要があります

import _string

ラインを交換します

first, rest = field_name._formatter_field_name_split() 

first, rest = _string.formatter_field_name_split(field_name) 
于 2013-05-09T09:23:13.443 に答える
1

これを行う唯一の方法は、dict および sequence プロトコルを実装するラッパー クラスを作成し、リストまたは dict の戻り値を同じクラスにラップし、KeyError または IndexError 例外をキャッチすることです。

その後、あなたの呼び出しは になり"…".format(**DefaultingWrapper(value))ます。

于 2013-05-09T08:51:04.570 に答える