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 vif v and k in ALLOWED_PARAMS.

正如帝斯曼建议的那样:

如果您正在运行 Python 2.7+,则可以使用dict comprehension
此版本还提供了“允许的变量”问题的替代方案:

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. 我认为您在使用时不需要ifs **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 回答