Python 使用函数值作为kwargs.get()默认值
在单元测试中,我有一个带有多个外键的模型的工厂函数。我希望工厂函数是可变的,允许用户指定作为外键使用的对象作为关键字参数,但调用相关工厂函数为遗漏的任何对象生成一个新的工厂函数 我最初是这样写的:Python 使用函数值作为kwargs.get()默认值,python,django,Python,Django,在单元测试中,我有一个带有多个外键的模型的工厂函数。我希望工厂函数是可变的,允许用户指定作为外键使用的对象作为关键字参数,但调用相关工厂函数为遗漏的任何对象生成一个新的工厂函数 我最初是这样写的: def model_factory(i, **kwargs): """Create a new Model for testing""" test_model_data = { 'fk1': kwargs.get('fk1', fk1_factory(i)),
def model_factory(i, **kwargs):
"""Create a new Model for testing"""
test_model_data = {
'fk1': kwargs.get('fk1', fk1_factory(i)),
'fk2': kwargs.get('fk2', fk2_factory(i)),
'fk3': kwargs.get('fk3', fk3_factory(i)),
}
return Model.objects.create(**test_model_data)
但这会调用fkN_factory()方法,即使关键字存在,也会导致许多副作用,干扰我的测试。我的问题是,是否有一种更简单的方法来完成我在这里想要做的事情,而不产生大量不必要的函数调用,而不是像我现在这样,更像:
def model_factory(i, **kwargs):
"""Create a new Model for testing"""
test_model_data = {
'fk1': kwargs.get('fk1', None),
'fk2': kwargs.get('fk2', None),
}
if kwargs['f1'] is None:
kwargs['f1'] = fk1_factory(i)
if kwargs['f2'] is None:
kwargs['f2'] = fk2_factory(i)
您希望以某种方式排除重复的代码。最简单的是:
def get_value(mapping, key, default_func, *args):
try:
return mapping[key]
except KeyError:
return default_func(*args)
# ...
test_model_data = {
'fk1': get_value(kwargs, 'fk1', fk1_factory, i),
'fk2': get_value(kwargs, 'fk2', fk2_factory, i),
# etc.
}
几乎和您的原始非工作版本一样简单
你可以更进一步:
def map_data(mapping, key_factory_map, *args):
return {key: get_value(mapping, key, factory, *args)
for key, factory in key_factory_map.items()}
# …
test_model_data = map_data(kwargs, {
'fk1': fk1_factory,
'fk2': fk2_factory,
# …
}, i)
但我不确定这是否真的更好。(如果您有一个明显的位置来定义工厂映射的键,那么它可能是;如果不是,那么可能不是。)这是一个非常好的重构。非常感谢。