1

私はRubyでメタプログラミングを学んでいて、それが非常に役立つことを発見しました。Pythonでも同じことができると確信しています。

例:メタプログラミングを使用して、この関数を簡潔かつ一般的な方法でこの関数に書き直すにはどうすればよいですか?

def foo(bar=None, baz=None, qux=None, haz=None):
    txt = {}

    if bar:
        txt.update({'bar': bar})
    if baz:
        txt.update({'baz': baz})
    if qux:
        txt.update({'qux': qux})
    if haz:
        txt.update({'haz': haz})

    return txt

(これは明らかに過度に単純化されており、実際には、個々のキーの値セットに基づいて異なるタスクを実行する可能性があります)

4

2 に答える 2

6

**kwargs次の構文を使用できます。

def foo(**kwargs):
    txt = {}
    for k, v in kwargs.items():
        if v:
            txt[k] = v
    return txt

または、インクが不足している場合:

def foo(**kwargs):
    return dict(((k,v) for k, v in kwargs.items() if v))

クレメントベロットによって提案されたように:

これらの引数が期待されるセットに含まれていることを確認したい場合は、ALLOWED_PARAMS = ('bar','baz','qux','haz')定数を使用して。に置き換えるif vことができますif v and k in ALLOWED_PARAMS

DSMによって提案されたように:

Python 2.7以降を実行している場合は、dict内包表記を使用できます。
このバージョンでは、「許可された変数」の問題に対する別の見方も提供されています。

def foo(bar=None, baz=None, qux=None, haz=None): 
    return {k:v for k,v in locals().items() if v}

そこにあるパラメータに応じて実際に関数を呼び出したいとしましょう。次のことができます。

KWARGS_TO_FUNCTIONS = {
    'bar':fn_bar,
    'baz':fn_baz, 
    'qux':fn_qux,
    'haz':fn_haz,
}

def foo(**kwargs):
    for k, v in kwargs.items():
        if v:
            try:
                KWARGS_TO_FUNCTIONS[k](v)
            except KeyError:
                pass # We didn't want that kwarg.

さて、全体として、それが本当に「メタ」であるかどうかは完全にはわかりません。

于 2012-10-29T00:42:47.520 に答える
3

Thomasは、を使用していくつかの実装を行い**kwargsました。ifを使用する場合、sは必要ないと思います**kwargs。元のコードでは、パラメータが省略されているかどうかをテストするために必要です。を使用する場合**kwargs、辞書には指定されたパラメーターが正確に含まれるため、必要なのは

def foo(**kwargs):
    return kwargs

この実装は必要ありませんdict()。代わりにコンストラクターを使用できます。

>>> dict(bar=1, baz=2, qux=3, haz=4)
{'qux': 3, 'haz': 4, 'baz': 2, 'bar': 1}
于 2012-10-29T01:19:50.200 に答える