简体   繁体   English

处理大量常数的最有效方法

[英]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个条件需要检查:

  • Language 语言
  • Provider 提供者

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. 另请注意, englishrussian是独立功能。 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: 除非操作同时取决于providerlanguage ,否则您需要双重地图:

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.

相关问题 在 python 中处理大列表的更有效方法? - More efficient way to handle big lists in python? 在列表 python 上计算大数字的有效方法 - Efficient way to count big number on list python count()是计算对象数量的最有效方法吗? - Is count() the most efficient way to count the number of objects? 寻找数字最后一位数的最有效方法是什么? - Most efficient way to look for the last digit of a number? 在Python中调整大图像大小的CPU效率最高的方法是什么 - What is the most CPU efficient way to resize big images in Python 检查会话是否仍然有效/处理 connectionError 的最有效方法? - Most efficient way to check if a session is still valid/handle connectionError? Python3:处理条形分隔文件的最有效方法是什么? - Python3: What is the most efficient way to handle bar delimited files? 正确/最有效的方式来处理Django模型和关系数据 - Proper/most efficient way to handle Django models and relational data 在 pygame 中处理多个玩家键输入的最有效方法是什么? - What is the most efficient way to handle multiple players key inputs in pygame? 最有效的方法(lo &lt;= k &amp;&amp; k &lt;= hi)? 1:0表示ka numpy数组,lo,hi常数 - Most efficient way to do (lo <= k && k <= hi) ? 1 : 0 for k a numpy array, lo, hi constants
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM