【发布时间】:2018-07-16 13:38:18
【问题描述】:
我在处理定义用户友好的函数接口时遇到了一些麻烦当使用相同的键传递两个关键字参数时。
问题
在两个关键字参数具有相同键且第二个关键字参数具有优先权的情况下,调用函数的最佳方法是什么?
如果出现此问题,第一个关键字参数始终来自 dict 中的解压缩数据库,而第二个关键字参数始终通过“直接”作为关键字参数传递。
数据库字典值不得在函数的外部副本中被覆盖,因为它们可能会被多次使用。
编辑:为了保持功能对用户的可用性,后端实现是首选。这意味着用户可以简单地将参数传递给函数,而无需使用额外的模块,而函数本身可以完成所有的魔法。
问题
我有一个函数,在这里称为fun_one,它接收由我的程序用户直接定义的大量参数。例如,这可能是热交换器的length 和width。为了简化函数的使用并使调用代码尽可能短,鼓励使用数据库。这些数据库包含dict(或熊猫系列)中的数据,在本例中称为inputs。
要将数据库-dict inputs 传递给函数,使用**inputs 解压缩并因此作为关键字参数传递。
现在如果用户想要覆盖数据库的特定参数,我对用户友好方法的理解是让他再次传递前面的参数,例如使用length=23.7,并在内部覆盖数据库中的参数。但是当然(参见示例代码),这会在我甚至可以输入可以try/except的函数之前引发错误:
TypeError: fun_one() 为关键字参数“长度”获取了多个值
重现错误的代码示例
def fun_one(*args, **kwargs): # short example function
print(kwargs)
inputs = {'length': 15.8, 'width': 1.1, 'some_other_args': np.random.rand(3)}
fun_one(**inputs, length=23.7)
我目前的解决方案
我当前的解决方案fun_two 涉及不解压缩数据库并将其传递给*args。它检查*args 中的dicts 并将kwargs 中尚未出现的值设置为kwargs,如下面的代码示例所示。
def fun_two(*args, **kwargs): # example function printing kwargs
print(kwargs) # print kwargs before applying changes
for arg in args: # find dicts
if type(arg) is dict:
for key, val in arg.items(): # loop over dict
_ = kwargs.setdefault(key, val) # set val if key not in dict
print(kwargs) # print kwargs after applying changes
inputs = {'length': 15.8, 'width': 1.1, 'some_other_args': np.random.rand(3)}
fun_two(inputs, length=23.7)
但是这种方法对用户来说非常晦涩难懂,并且需要在很多函数的开头进行循环和检查,因为这将适用于许多函数。 (我会把它外包给一个模块,所以每个函数一行一行。但它仍然偏离了我对简单明了的函数定义的理解)。
有没有更好(更 Pythonic)的方法来做到这一点?在调用函数的过程中,我是否监督了一些方法?性能无关紧要。
提前致谢!
【问题讨论】: