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])
这假定您可以有两个需要检查的等效条目。然后对于任何条目,字典将函数调用和一个字符串存储在列表中,主函数将调用该列表。
我想尝试在我的代码中重构这个方法:
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])
这假定您可以有两个需要检查的等效条目。然后对于任何条目,字典将函数调用和一个字符串存储在列表中,主函数将调用该列表。