从文件加载方法参数

时间:2017-03-04 00:16:44

标签: python parameters metaprogramming kwargs

假设我有一个带有一些参数的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']

然而,这是不可能的,因为我现在已经需要通过代码传递ab,否则我将得到一个TypeError:

my_function(config_file="~/config.yaml")
TypeError: my_function() takes at least 2 arguments (1 given)

当然,我可以为每个参数指定默认值,但在某些情况下,这是没有意义的。我想强制将此参数传递给函数。 理想情况下,我希望像往常一样使用和不使用默认值来指定我的函数,最后使用**kwargs。然后我解析配置文件,该文件通过那些**kwargs传递给函数。我将所有缺少的参数替换为文件中的对应参数,如果没有缺省参数的参数丢失,则抛出错误。

我怎样才能实现这一目标?可能吗?我并不反对某些元编程(或另一种完全不同的方法来处理这个问题)。

1 个答案:

答案 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