假设我有一个带有一些参数的python函数:
def my_function(a, b, c=1):
print a, b, c
这个函数是一个更大的管道的一部分,它有很多参数。 我经常想用不同的参数调用这个管道,所以我设计了一个配置文件格式和一个解析器来读取它。 其中一些参数需要传递给不同的函数。
所以我重新设计了能够从文件中获取内容的函数(为了简洁,我在这里跳过错误检查等):
def my_function(c=1, **kwargs):
config = load_config(kwargs.pop(["config_file"]))
# config is now {'a': 10, 'b': 5}
config['c'] = c
# config is now {'a': 10, 'b': 5, 'c': 1}
print config['a'], config['b'], config['c']
我现在可以通过代码和配置文件传递参数。
但是,我无法强制kwargs
中存在给定参数,而无需提供所需参数的完整列表并检查它们是否全部存在。
现在问题在于,如果不查看代码,没有人真正知道my_function
需要什么样的参数。
我想要的是以下内容:
def my_function(a, b, c=1, **kwargs):
config = load_config(kwargs.pop(["config_file"]))
# config is now {'a': 10, 'b': 5}
config['c'] = c
# config is now {'a': 10, 'b': 5, 'c': 1}
print config['a'], config['b'], config['c']
然而,这是不可能的,因为我现在已经需要通过代码传递a
和b
,否则我将得到一个TypeError:
my_function(config_file="~/config.yaml")
TypeError: my_function() takes at least 2 arguments (1 given)
当然,我可以为每个参数指定默认值,但在某些情况下,这是没有意义的。我想强制将此参数传递给函数。
理想情况下,我希望像往常一样使用和不使用默认值来指定我的函数,最后使用**kwargs
。然后我解析配置文件,该文件通过那些**kwargs
传递给函数。我将所有缺少的参数替换为文件中的对应参数,如果没有缺省参数的参数丢失,则抛出错误。
我怎样才能实现这一目标?可能吗?我并不反对某些元编程(或另一种完全不同的方法来处理这个问题)。
答案 0 :(得分:1)
你只能轻易地为kwargs做这个,因为它们已被命名。这样的事情应该有效:
vargs = (1,2,3)
kwargs = {"c": 4, "d": 5}
config_kwargs = load_config("things.config")
kwargs.update(config_kwargs) # merge the kwargs from the config file over the defaults
my_function(*vargs, **kwargs) # apply the args to the function