仅展开功能所需的键值对

swigganicks:

假设我们有一个带有一些参数的函数和一个dict,它是调用该函数所需的值的超集:

d = {"a": 1, "b": 2, "c": 3}

def foo(a, b):
   print(a, b)

# this won't work
foo(**d)

# this works but is tedious the more values there are
foo(**{k: v for k,v in d.items() if k not in ("c")})

有没有更优雅的解决方案?

int6h:

而不是这样做:

def foo(a, b):
   print(a, b)

您可以这样做:

def foo(a, b, **kwargs):
   print(a, b)

然后,该函数将忽略所有不需要的参数。

但是,我认为这种方法存在一些问题。

  1. 有时您不拥有该函数的源代码。当然,您可以创建很多包装函数。如果您手动执行此操作,则每次库作者修改函数签名时,都必须更改辅助函数的签名。

  2. 此解决方案会使一些错误更难找到。最好明确声明您仅使用字典中的某些元素。

您仍然可以使用inspect标准库模块使其变得更容易

a)创建一个装饰器,使该函数过滤其关键字参数。

例如:

import inspect

def filter_kwargs(f):
  arg_names = inspect.getargspec(f).args
  def _f(*args, **kwargs):
    return f(*args, **{k: v for k, v in kwargs.items() if k in arg_names})
  return _f

# Use it like this:
filter_kwargs(foo)(a_dict)

b)您可以创建一个将参数转换为适合该函数的函数

def fit_for(f, kwargs):
  arg_names = inspect.getargspec(f).args
  return {k: v for k, v in kwargs.items() if k in arg_names}

foo(fit_for(foo, a_dict))

(可选)您可以扩展此功能以同时考虑*args**kwargs在原始功能中。


如果这是代码中的重复模式,则只需将dict作为单个参数传递即可。

另外,正如@chepner在评论中指出的那样,请考虑创建一个类。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章