簡體   English   中英

處理大量常數的最有效方法

[英]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 另請注意, englishrussian是獨立功能。 最后, 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 除非操作同時取決於providerlanguage ,否則您需要雙重地圖:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM