你可以用字典理解中的一行来做到这一点:
{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
this 函数中的属性或方法,则将在此函数上运行,这可能会导致问题。我建议更改该属性或方法的名称,或将检查替换为isinstance(dict)
.
我还想指出,对于rand_int
返回字符串'yes'
或的误导性函数名称'no'
可能与它得到的一样糟糕。通常,您也希望True
/False
在这些情况下。
如评论中所述,在 Python 2.7 之前,您可能没有字典理解。为了解决这个问题,dict()
将使用元组生成器,因此您可以像这样替换 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'}}