6

簡単に言えば、ルックアップを実行する任意の名前の引数を使用してformatを呼び出したいと思います。

'{Thing1} and {other_thing}'.format(**my_mapping)

私は次のようにmy_mappingを実装しようとしました:

class Mapping(object):
  def __getitem__(self, key):
    return 'Proxied: %s' % key
my_mapping = Mapping()

を呼び出すと、これは期待どおりに機能しmy_mapping['anything']ます。しかし、上記のようにformat()に渡されると、次のようになります。

TypeError: format() argument after ** must be a mapping, not Mapping

dictの代わりにサブクラス化を試みましたが、次に示すようにobject呼び出すと、が発生します。私もとして実装しましたが、それでも。format()KeyError__contains__return TrueKeyError

つまり、渡されたオブジェクトを**呼び出すだけではないよう__getitem__です。これを回避する方法を知っている人はいますか?

4

4 に答える 4

6

string.FormatterPython 2では、クラスを使用してこれを行うことができます。

>>> class Mapping(object):
...     def __getitem__(self, key):
...         return 'Proxied: %s' % key
...
>>> my_mapping = Mapping()
>>> from string import Formatter
>>> Formatter().vformat('{Thing1} and {other_thing}', (), my_mapping)
'Proxied: Thing1 and Proxied: other_thing'
>>>

vformatフォーマット文字列、位置フィールドのシーケンス、キーワードフィールドのマッピングの3つの引数を取ります。位置フィールドは必要ないため、空のタプルを使用しました()

于 2011-11-21T22:14:43.890 に答える
5

Python 3.2以降:

'{Thing1} and {other_thing}'.format_map(my_mapping)
于 2011-11-21T21:24:07.313 に答える
2

これは少し降霊術かもしれませんが、私は最近この問題に遭遇し、このSOの質問が最初の結果でした。を使用することに満足していなかったので、 Just Work (TM)string.Formatterを使用したかったのです。

keys()クラスと同様に関数__getitem__()を実装すると、が機能します**my_mapping

すなわち:

class Mapping(object):

  def __getitem__(self, key):
    return 'Proxied: %s' % key

  def keys(self):
    return proxy.keys()

どこ

>>> my_mapping = Mapping()
>>> my_mapping.keys()
['Thing1','other_thing',...,'Thing2']

で機能するマッピングが成功し.formatます。

どうやら(私は実際にのソースを見ていませんがstr.format)、keys()キーのリストを取得し、文字列で指定された識別子をそれらのキーにマップし__getitem__()、指定された値を取得するために使用しているようです。

お役に立てれば。

編集

@ aaron-mcmillinの位置にいて、キーセットが大きい場合、考えられるアプローチは、キーの完全なセットを生成するのではなく、より小さなサブセットを生成することです。もちろん、これは、小さなサブセットをフォーマットするだけでよいことがわかっている場合にのみ機能します。

すなわち:

class Mapping(object):
  ...
  def keys(self):
    return ['Thing1','other_thing', 'Thing2']
于 2014-10-27T18:41:12.463 に答える
1

これは私が思いつくことができる最高のものです:

キーワード引数をとってfuncに渡すカスタムマッピングオブジェクトがある場合は、キーのセット(動的に生成される場合がありますが、有限のセットである必要があります)が必要であり、次のことが可能である必要があります。どういうわけかそれらのキーをマッピングします。__iter__したがって、キーを取得する必要が__getitem__あり、それらのキーごとに成功すると想定できる場合は、次のようになります。

class Me(object):
    def __init__(self):
        pass

    def __iter__(self):
        return iter(['a', 'b', 'c'])

    def __getitem__(self, key):
        return 12

関数は次のとおりです。

def myfunc(**kwargs):
    print kwargs, type(kwargs)

次に、口述を行うことでそれを渡すことができます。

m = Me()
myfunc(**dict((k, m[k]) for k in m))

その結果:

{'a': 12, 'c': 12, 'b': 12} <type 'dict'>

どうやらこれはそれが行われる方法でなければなりません...から派生したオブジェクトを渡したとしてもdict、関数はまだdictkwargsのためにを持っています:

class Me(dict): pass

m = Me()
print type(m) #prints <class '__Main__.Me'>

def myfunc(**kwargs):
    print type(kwargs)
myfunc(**m) #prints <type 'dict'>

特定の鍵盤を意識せずに、鍵盤の内容に基づいて値を返すようなことをしたいと思っているようですので、このformat関数は使えないようです。

于 2011-11-21T22:50:20.317 に答える