1

オブジェクトを使用することを考えましたが、この場合にどのように役立つかわかりません。何か案は?

from random import choice
from copy import deepcopy


def main():

    def rand_int():
        return choice(['yes', 'no'])

    # any nesting, functions possible
    spec = {
        'answer': rand_int,
        'next': {'answer': rand_int},
        'the_answer': 42
    }

    #### looking for elegant (automatic) way to do this
    result = deepcopy(spec)
    result['answer'] = result['answer']()
    result['next']['answer'] = result['next']['answer']()
    #### until here

    # result2 = ...

    print 'result: %s' % result


if __name__ == '__main__':
    main()

xsd を使うように言わないでください!

4

1 に答える 1

8

これは、辞書内包表記の 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'TrueFalse

コメントで述べたように、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'}}
于 2012-05-09T10:32:04.443 に答える