8

値を個別に評価するPythonディレクトリを作成したいと思います。

したがって、たとえば、次の機能しない例では、次のように定義します

a = {'key1': 'value1', 'key2': 42, 'key3': foo(20)}

たとえば

def foo(max):
    """Returns random float between 0 and max."""
    return max*random.random()

そして、口述の処理後、私は例えば

a_processes = {'key1': 'value1', 'key2': 42, 'key3': 12.238746374}

keyの値key3はすぐに評価され、foo(20)呼び出し可能ではないため、この例は機能しません。それが機能する方法は、次のようなものを使用することです

a = {'key1': 'value1', 'key2': 42, 'key3': foo}

しかし、ここでfooはその議論を見逃します。これを処理する1つの方法は、次の方法でdictを定義することです。

a = {'key1': 'value1', 'key2': 42, 'key3': [foo, 20]}

次の処理スキームで

a_processed = dict([k,process(v)] for k,v in a.items())

これprocessは、引数がリストであるかどうか、または最初の要素が残りの引数で呼び出される呼び出し可能であるかどうかをチェックする意味のある関数です。

私の質問は、私の基本的なアイデアを実装するためのより良い方法/アイデアについてですか?

4

2 に答える 2

9

を使用しfunctools.partial()て、一連の引数を別の呼び出し可能オブジェクトに適用する呼び出し可能オブジェクトを作成します。

from functools import partial

a = {'key1': 'value1', 'key2': 42, 'key3': partial(foo, 20)}

これで、key3値は呼び出し可能なオブジェクトになります。a['key3']()順番に呼び出しfoo(20)て結果を返します。

この辞書を「処理」する必要があります(callable()関数でテストする:

{k: v() if callable(v) else v for k, v in a.iteritems()}

もちろん。Python 3を使用している場合は、a.items()代わりにを使用してください。

functools.partialセットアップでは、必要に応じて引数を追加できます(サポートfoo()されている場合)。

a['key3']('additional', arguments='accepted')

キーにアクセスするときにこれを自動的に行う辞書サブクラスを作成することもできます。

def CallablesDict(dict):
    def __getitem__(self, key):
        value = super(CallablesDict, self).__getitem__(key)
        return value() if callable(value) else value

次に、次のように定義aします。

a = CallablesDict({'key1': 'value1', 'key2': 42, 'key3': partial(foo, 20)})

print a['key3']  # calls foo(20)
于 2013-01-30T17:48:53.413 に答える
6

lambda構文が好きだからという理由で、ここでは引数なしを使用することがよくあります。

>>> def foo(x):
...     return x*100
... 
>>> a = {'key1': 'value1', 'key2': 42, 'key3': lambda: foo(20)}
>>> a
{'key3': <function <lambda> at 0x96ae80c>, 'key2': 42, 'key1': 'value1'}
>>> {k: v() if callable(v) else v for k,v in a.iteritems()}
{'key3': 2000, 'key2': 42, 'key1': 'value1'}
于 2013-01-30T17:50:19.243 に答える