[英]Most efficient way to handle big number of constants
我正在编写一个程序,该程序根据Excel表中的某些值进行API调用。 表格中有2个条件需要检查:
根据这两个值,API调用需要一组不同的常量:
def run_workflow(provider, language, workflow):
if provider == 'xxxx' and language == 0:
wf_ready = provider_ready
wf_unverified = provider_unverified
wf_active = provider_active
wf_another = provider_another
wf_closed = provider_closed
wf_wrongid = provider_wrongid
elif provider == 'yyyy' and language == 0:
wf_ready = provider_ready
wf_unverified = provider_unverified
wf_active = provider_active
wf_another = provider_another
wf_closed = provider_closed
wf_wrongid = provider_wrongid
elif ...
if workflow == 'ready':
response = requests.post(API + wf_ready),headers=header, data=json.dumps(conversation))
elif workflow == 'unverified':
response = requests.post(API + wf_unverified),headers=header, data=json.dumps(conversation))
elif ...
有2种提供程序和7种不同的语言,我试图找出最有效(和Pythonic的方式)来处理这种情况,并想出为每种语言创建一个类:
class Workflow_Language():
def english(self):
self.provider_unverified = 1112
self.provider_ready = 1113
self.provider_active = 1114
self.provider_vip = 1115
def russian(self):
self.provider_unverified = 1116
self.provider_ready = 1117
self.provider_active = 1118
self.provider_vip = 1119
def ...
...
有没有更好的方法来解决这个问题?
一种方法是将常量映射到适当的处理程序:
class LanguageData:
def __init__(self, unverified, ready, active, vip):
self.unverified = unverified
self.ready = ready
self.active = active
self.vip = vip
def english():
return LanguageData(1,2,3,4)
def russian():
return LanguageData(5,6,7,8)
LANGUAGE_MAP = {'en': english, 'ru': russian}
为了清楚起见'en', 'ru'
我编造了'en', 'ru'
值。 您的情况似乎是0
? 另请注意, english
和russian
是独立功能。 最后, LanguageData
类不是必需的,您可以简单地从这些函数返回字典。 但是使用属性而不是字符串键进行维护似乎更容易。
然后在代码中:
def run_workflow(provider, language, workflow):
lang_data = LANGUAGE_MAP[language]()
if workflow == 'ready':
url = API + data.ready
elif workflow == 'unverified':
url = API + data.unverified
response = requests.post(url, headers=header, data=json.dumps(conversation))
当然,如果有两个以上的可能值,则可以用类似的方式包装workflow
。
类似地提供provider
。 除非操作同时取决于provider
和language
,否则您需要双重地图:
LANG_PROV_MAP = {
('en', 'xxxx'): first,
('ru', 'yyyy'): second,
}
def run_workflow(provider, language, workflow):
data = LANG_PROV_MAP[(provider, language)]()
...
原始代码可以使用棘手的装饰器进行简化:
LANGUAGE_MAP = {}
def language_handler(lang):
def wrapper(fn):
LANGUAGE_MAP[lang] = fn
return fn
return wrapper
@language_handler('en')
def handler():
return LanguageData(1,2,3,4)
@language_handler('ru')
def handler():
return LanguageData(5,6,7,8)
还要注意,如果数据是“恒定的”(即不依赖于上下文),则可以完全省略可调用对象以使所有内容变得更简单:
LANGUAGE_MAP = {
'en': LanguageData(1,2,3,4),
'ru': LanguageData(5,6,7,8),
}
def run_workflow(provider, language, workflow):
data = LANGUAGE_MAP[language]
...
语言和提供程序的组合可以组成方法名称,并且调用将被动态调用。
例:
import sys
def provider1_lang2():
pass
def provider2_lang4():
pass
# get the provider / lang and call the method dynamically
provider = 'provider2'
lang = 'lang4'
method_name = '{}_{}'.format(provider,lang)
method = getattr(sys.modules[__name__], method_name)
method()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.