これは、辞書内包表記の 1 行で実行できます。
{key: function() for key, function in mydictionary.items()}
もちろん、値が関数でない場合、これはエラーをスローするため、その可能性がある場合は、callable()
組み込みのチェックを追加するだけです。
{key: (function() if callable(function) else function) for key, function in mydictionary.items()}
次に、答えを再帰的にする必要があるという事実に対処する必要があります。これにより、少し複雑になりますが、修正するのはそれほど難しくありません。
def call_all_callables_in_dict(mapping):
if hasattr(mapping, "items"):
return {key: call_all_callables_in_dict(value) for key, value in mapping.items()}
elif callable(mapping):
return mapping()
else:
return mapping
この関数items
に保存したい属性またはメソッドを持つオブジェクトが実行される場合、問題が発生する可能性があることに注意してください。dict
その属性またはメソッドの名前を変更するか、チェックを に置き換えることをお勧めしisinstance(dict)
ます。
また、またはrand_int
の文字列を返す誤解を招くような関数名については、おそらくそれと同じくらい悪いことに注意してください。一般的には/そのような状況でも必要です。'yes'
'no'
True
False
コメントで述べたように、Python 2.7 より前では、辞書内包表記がない場合があります。これを回避するにdict()
は、タプルのジェネレーターを使用するため、次のように辞書内包表記を置き換えることができます。
{x: y for x, y in something.items()}
と:
dict((x, y) for x, y in something.items())
したがって、完全には:
from random import choice
def rand_int():
return choice(['yes', 'no'])
spec = {
'answer': rand_int,
'next': {'answer': rand_int},
'the_answer': 42
}
def call_all_callables_in_dict(mapping):
if hasattr(mapping, "items"):
return {key: call_all_callables_in_dict(value) for key, value in mapping.items()}
elif callable(mapping):
return mapping()
else:
return mapping
print(call_all_callables_in_dict(spec))
私たちに与えます:
{'answer': 'no', 'the_answer': 42, 'next': {'answer': 'yes'}}