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)

但我不确定这是否真的更好。(如果您有一个明显的位置来定义工厂映射的键,那么它可能是;如果不是,那么可能不是。)

这是一个非常好的重构。非常感谢。