簡體   English   中英

解包關鍵字參數,但只包含與函數匹配的參數

[英]Unpacking keyword arguments, but only the ones that match the function

假設我有一個功能:

def foo(a=None, b=None, c=None):
  return "a:%s, b:%s, c:%s" % (a, b, c)

我有一個上面有一些(或沒有)參數的字典,但也有一個在函數中沒有命名參數的鍵,例如:

d = {'a': 1, 'x': 4, 'b': 2, 'y': 5}

如果我調用以下內容,我將收到錯誤,因為'x'和'y'不是foo函數中的關鍵字參數。

foo(**d)  # error

是否有一種優雅的方式將參數從字典傳遞給函數,但只有那些具有與函數參數匹配的鍵的值。

如果我的參數/參數術語關閉,請糾正我。

def foo(a = None, b=None, c=None,**extras):
    return "a:%s, b:%s, c:%s" % (a, b, c)

這里**extras將收集所有額外的命名/關鍵字參數。

@Ashwini Chaudhary有一種非常pythonic的方式來解決你的問題。 但是,它需要更改foo函數的簽名。

如果您不想更改函數簽名,可以使用內省來查找函數所期望的參數:

arg_count = foo.func_code.co_argcount
args = foo.func_code.co_varnames[:arg_count]

args_dict = {}
for k, v in d.iteritems():
    if k in args:
        args_dict[k] = v

foo(**args_dict)

有趣的問題。 我認為現實生活中的大多數人都使用@Ashwini Chaudhary的方法。

我同意@Rodrigue有時候你不能修改函數的調用簽名(也許是其他人的模塊)

發生這種情況時, 請使用函數裝飾器

from inspect import getargspec
from funtools import wraps

def allow_kwargs(foo):
    argspec = getargspec(foo)
    # if the original allows kwargs then do nothing
    if  argspec.keywords:
        return foo
    @wraps(foo)
    def newfoo(*args, **kwargs):
        #print "newfoo called with args=%r kwargs=%r"%(args,kwargs)
        some_args = dict((k,kwargs[k]) for k in argspec.args if k in kwargs) 
        return foo(*args, **some_args)
    return newfoo


# with your function:
@allow_kwargs
def foo(a = None, b=None, c=None):
  return "a:%s, b:%s, c:%s " % (a,b,c)

# with someone_elses function:
from some_place import foo
foo = allow_kwargs(foo)

@wraps從functools保持__name____doc__機智字符串。 你也可以:

  • 從裝飾器模塊看看FunctionMaker ,但這應該是一種更可重用的方法。
  • 修改newfoo以允許不傳遞額外的非關鍵字變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM