我正在编写一个程序,该程序根据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 ...
...
也许有更好的方法来解决这个问题?
答案 0 :(得分:2)
一种方法是将常量映射到适当的处理程序:
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'
个值。看来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]
...