1

我一直在Ruby中學習元編程,並發現它非常有用。我相信我可以在Python中做同樣的事情。基本的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 

(這顯然是過於簡單化,在實踐中,人們可能會執行基於價值設定的各個鍵不同的任務)

+3

除非我的思念很明顯,我不認爲這個問題與Python元編程有什麼關係? –

回答

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)) 

A ŝ建議克萊門特貝洛特:

如果你想確保那些ARG遊戲在您的預計集,你可以有一個ALLOWED_PARAMS = ('bar','baz','qux','haz')常數,與if v and k in ALLOWED_PARAMS取代if v

作爲建議由DSM:

如果你正在運行的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. 

現在,總而言之,我不完全確定這真的是'元'。

+0

可以在{'bar','baz','qux','haz'}'中爲'k添加一個測試。 –

+0

@ClementBellot嗯,我不確定這是什麼預期的問題,但我會加上它,是的 –

+0

'def foo(bar = None,baz = None,qux = None,haz = None):return {k :v for k,v in locals()。items()if v}'也可以。我認爲OP的代碼有一個bug,如果bar不是None,那麼'foo(bar = 0)'不會加載字典。但是,如果沒有關於OP究竟在做什麼的更多信息,很難看出元編程是如何有用的。 – DSM

3

托馬斯給出了一些使用**kwargs的實現。 我認爲您在使用**kwargs時不需要if。在原始代碼中,它們是測試參數是否被省略的必要條件。當使用**kwargs,詞典將僅包含給定的參數,所以我們需要的是

def foo(**kwargs): 
    return kwargs 

甚至不需要這種實現方式 - 你可以使用dict()構造來代替:

>>> dict(bar=1, baz=2, qux=3, haz=4) 
{'qux': 3, 'haz': 4, 'baz': 2, 'bar': 1}