Python 重构方法中的 if-elif-else 语句

Python refactoring if-elif-else statements in method

我想尝试在我的代码中重构这个方法:

def get_params_in_string(params):
    obj_name = params.PrefetchMethod.split('.')[0]

    right_method_name = 'BuhReports.'

    if obj_name in ('AccountAnalysisW', 'АнализСчетаW'):
        obj = AccountAnalysis(None, params, None, None)
        method_name = right_method_name + 'GetAccountAnalysis'
    elif obj_name in ('TurnoverSheetW', 'ОборотнаяВедомостьW'):
        obj = TurnoverSheet(None, params, None, None)
        method_name = right_method_name + 'GetTurnoverSheet'
    elif obj_name in ('CardAccountW', 'КарточкаСчетаW'):
        obj = CardAccount(None, params, None, None)
        method_name = right_method_name + 'GetCardAccount'
    elif obj_name in ('MutualSettlementsW', 'ВзаиморасчетыW'):
        obj = MutualSettlements(None, params, None, None)
        method_name = right_method_name + 'GetMutualSettlements'
    elif obj_name in ('JournalVoucherW', 'ЖурналОрдерW'):
        obj = JournalVoucher(None, params, None, None)
        method_name = right_method_name + 'GetJournalVoucher'
    elif obj_name in ('WarehouseCompareW', 'СверкаСкладаW'):
        obj = WarehouseCompare(None, params, None, None)
        method_name = right_method_name + 'GetWarehouseCompare'
    elif obj_name in ('DebtsW', 'ДолгиW'):
        obj = Debts(None, params, None, None)
        method_name = 'MutualSettlements.DebitorsAndCreditors'
    else:
        raise Exception('Unexpected call')

    obj.prepare_filters()
    params.Put('PrefetchMethod', method_name, sbis.FieldType.ftSTRING)
    return JournalVoucher.GetParamsInString(params)

这里有个问题。我不喜欢很多重复的代码。在我看来,这里可以使用某种模式,但我不知道是哪一种。这种情况有什么解决办法吗?

您可以使用字典来存储可比较的值,然后使用 .get 获取该值,或者如果它不存在 return 给定的参数值(给定 None但这也是默认设置):

dct = {
    ('AccountAnalysisW', 'АнализСчетаW'): {'name': 'GetAccountAnalysis', 'obj': AccountAnalysis},
    ('TurnoverSheetW', 'ОборотнаяВедомостьW'): {'name': 'GetTurnoverSheet', 'obj': TurnoverSheet},
    ('CardAccountW', 'КарточкаСчетаW'): {'name': 'GetCardAccount', 'obj': CardAccount}
}
# create the dictionary with individual keys (basically unpack tuples
# and give the values in tuples their own value in the dict)
dct = {k: v for k, v in dct.items() for k in k}


def get_params_in_string(params):
    obj_name = params.PrefetchMethod.split('.')[0]
    right_method_name = 'BuhReports.'
    items = dct.get(obj_name, None)
    # if the key doesn't exist in the dictionary
    # then raise an exception
    if items is None:
        raise Exception('Unexpected call')
    obj = items.get('obj')(None, params, None, None)
    method_name = right_method_name + items.get('name')

    obj.prepare_filters()
    params.Put('PrefetchMethod', method_name, sbis.FieldType.ftSTRING)
    return JournalVoucher.GetParamsInString(params)

以下是如何使用字典重构代码的最小示例:

def foo_1(params):
    return params[0]*2

def foo_2(params):
    return params[0]*3

def run_ops(entry, params):
    # Mapping between equivalent entries
    entry_map = {'AccountAnalysisW':'АнализСчетаW', 'WarehouseCompareW':'СверкаСкладаW'}
    # Dictionary with operations for each entry
    entry_ops = {'АнализСчетаW': [foo_1, 'Foo1'], 'СверкаСкладаW': [foo_2, 'Foo2']}

    if entry in entry_map:
        entry = entry_map[entry]

    if entry in entry_ops:
        ops = entry_ops[entry]
        res = ops[0](params)
        print('Calling ' + ops[1] + ' with a result ' + str(res))

run_ops('WarehouseCompareW', [1,2,3])
run_ops('АнализСчетаW', [4,5])

这假定您可以有两个需要检查的等效条目。然后对于任何条目,字典将函数调用和一个字符串存储在列表中,主函数将调用该列表。