[英]Most efficient way to handle big number of constants
I am writing a program that, depending on a certain values from an Excel table, makes an API call. 我正在编写一个程序,该程序根据Excel表中的某些值进行API调用。 There are 2 conditions from the table that will be checked:
表格中有2个条件需要检查:
Depending on those two values a different set of constants is needed for the API call: 根据这两个值,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 ...
There are 2 provider and 7 different languages and I am trying to figure out the most efficient (and Pythonic way) to handle this scenario and came up with creating a class for each language: 有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 ...
... ...
Is there maybe a better way to handle this? 有没有更好的方法来解决这个问题?
One way is to map constants to appropriate handlers: 一种方法是将常量映射到适当的处理程序:
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}
I've made up 'en', 'ru'
values for clarity. 为了清楚起见
'en', 'ru'
我编造了'en', 'ru'
值。 It seems that 0
is in your case? 您的情况似乎是
0
? Also note that english
and russian
are standalone functions. 另请注意,
english
和russian
是独立功能。 Finally the LanguageData
class is not mandatory, you can simply return a dictionary from those functions. 最后,
LanguageData
类不是必需的,您可以简单地从这些函数返回字典。 But workin with attributes instead of string keys seems easier to maintain. 但是使用属性而不是字符串键进行维护似乎更容易。
And then in the code: 然后在代码中:
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))
Of course workflow
can be wrapped in a similar way if there are more than 2 possible values. 当然,如果有两个以上的可能值,则可以用类似的方式包装
workflow
。
Analogously for provider
. 类似地提供
provider
。 Unless the action depends on both provider
and language
at the same time in which case you need a double map: 除非操作同时取决于
provider
和language
,否则您需要双重地图:
LANG_PROV_MAP = {
('en', 'xxxx'): first,
('ru', 'yyyy'): second,
}
def run_workflow(provider, language, workflow):
data = LANG_PROV_MAP[(provider, language)]()
...
The original code can be simplified with a tricky decorator: 原始代码可以使用棘手的装饰器进行简化:
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)
Also note that if the data is "constant" (ie doesn't depend on the context) then you can completely omit callables to make everything even simplier: 还要注意,如果数据是“恒定的”(即不依赖于上下文),则可以完全省略可调用对象以使所有内容变得更简单:
LANGUAGE_MAP = {
'en': LanguageData(1,2,3,4),
'ru': LanguageData(5,6,7,8),
}
def run_workflow(provider, language, workflow):
data = LANGUAGE_MAP[language]
...
The combination of the language and provider can compose the method name and the call will be invoked dynamically. 语言和提供程序的组合可以组成方法名称,并且调用将被动态调用。
Example: 例:
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.