【问题标题】:Switch case with 3 variables具有 3 个变量的开关盒
【发布时间】:2020-09-02 19:22:46
【问题描述】:

我可以用三个变量编写一个 switch/case 语句来替换这段代码吗:

 if where_clause == 0:
   requete(liste_fields,schema,table)
 elif where_clause == 1:
   if like_clause == 0:
     if any_clause == 1:
        requete_where_any(liste_fields,schema,table,wc_1,any_1)
     else:
        requete_where(liste_fields,schema,table,wc_1,wc_2)
   elif like_clause == 1:
        requete_like(liste_fields,schema,table,like_1,like_2)
 elif where_clause == 2:
        requete_double_where(liste_fields,schema,table,wc_1,wc_2,wc_3,wc_4)
 elif where_clause == 3:
        requete_triple_or(liste_fields,schema,table,oc_1,oc_2,oc_3,oc_4,oc_5,oc_6)

【问题讨论】:

标签: python switch-statement


【解决方案1】:

您可以使用以下函数定义来模拟 switch 语句:

def switch(v): yield lambda *c:v in c

您的代码可能如下所示:

for case in switch(where_clause):

    if case(0):
       requete(liste_fields,schema,table)
       break

    if case(1):
       for case in switch(like_clause): 
           if case(0):
               if any_clause == 1:
                   requete_where_any(liste_fields,schema,table,wc_1,any_1)
               else:
                   requete_where(liste_fields,schema,table,wc_1,wc_2)
               break

           if case(1):
               requete_like(liste_fields,schema,table,like_1,like_2)
      break
    
   if case(2):
      requete_double_where(liste_fields,schema,table,wc_1,wc_2,wc_3,wc_4)
      break

   if case(3):      
      requete_triple_or(liste_fields,schema,table, oc_1,oc_2,oc_3,oc_4,oc_5,oc_6)
      break 

注意,你不必使用case这个词,你可以选择更有意义的:

for where in switch(where_clause):

    if where(0):
       requete(liste_fields,schema,table)
       break

    if where(1):
       for like in switch(like_clause): 
           if like(0):
               if any_clause == 1:
                   requete_where_any(liste_fields,schema,table,wc_1,any_1)
               else:
                   requete_where(liste_fields,schema,table,wc_1,wc_2)
               break

           if like(1):
               requete_like(liste_fields,schema,table,like_1,like_2)
      break
    
   if where(2):
      requete_double_where(liste_fields,schema,table,wc_1,wc_2,wc_3,wc_4)
      break

   if where(3):      
      requete_triple_or(liste_fields,schema,table, oc_1,oc_2,oc_3,oc_4,oc_5,oc_6)
      break 

【讨论】:

    【解决方案2】:

    我做了一个 switch 类。它使用值初始化,其中键、值对将每个值的操作表示为包含函数和可选参数以及可选默认操作的列表。 例如,您应该这样称呼它:

    sw = switch(some_value, 
         {
             1:[print, 'hello'], 
             2:[print, 'goodby']
         },
         default=[print])
    

    默认参数没有参数,所以只打印一个新行。

    调用开关时调用对应的函数:

    sw()
    

    好在switch对象有__call__方法,开关可以嵌套。

    这是您的案例的实现和应用:

    class switch(dict):
        def __init__(self, value, cases, default = ((lambda:None),)):
            super().__init__(cases)
            self.default = default
            self.value = value
    
        def __call__(self):
            do = self.get(self.value, self.default)
            return do[0](*do[1:])
    
    sw = switch(where_clause, 
         {
            0: [requete],
            1: [switch(like_clause, 
                {   
                    0: [switch(any_clause, 
                       {   
                           1: [requete_where_any,liste_fields,schema,table, wc_1, any_1]
                       },  
                       default=[requete_where,liste_fields,schema,table, wc_1, wc_2])],
    
                    1: [requete_like,liste_fields,schema,table, like_1, like_2]
                },  
                default=[requete_like,liste_fields,schema,table, like_1, like_2])],
    
            2: [requete_double_where,liste_fields,schema,table, wc_1, wc_2, wc_3, wc_4),
            3: [requete_triple_or,liste_fields,schema,table, oc_1, oc_2, oc_3, oc_4]    
         })
    
    sw()
    

    可以很容易地改进该类,可以选择在初始化时不传递值,并在调用时传递值,例如:

    sw = switch( 
         {
             1:[print, 'hello'], 
             2:[print, 'goodby']
         })
    sw(1)  # -> 'hello'
    sw(2)  # -> 'goodby'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多