【问题标题】:Any idea for a more elegant / simplest conditionnal return?对更优雅/最简单的条件返回有任何想法吗?
【发布时间】:2022-11-14 09:25:31
【问题描述】:

这是python代码:

def _get_handler_by_topic_arn(topic_arn: str, event_name: str, event_message: dict):
if topic_arn == CONFIG.get("MT_MAIN_SNS_TOPIC_ARN"):
    return MT_MAIN_TOPIC_HANDLERS.get(event_name)
if topic_arn == CONFIG.get("FOX_REQUEST_SNS_TOPIC_ARN"):
    return FOX_REQUEST_TOPIC_HANDLERS.get(event_name)
if topic_arn == CONFIG.get("FOX_ORDER_RESULTS_SNS_TOPIC_ARN"):
    if event_message.get("status") and event_message.get("status") != "CANCELLED":
        return None
    return FOX_ORDER_RESULTS_TOPIC_HANDLERS.get(event_name)
return None

它有效,但我正在寻找一种更有效/优雅/最简单的方法来做同样的事情。如果你有任何想法,我会接受的:)。

【问题讨论】:

    标签: python


    【解决方案1】:

    我会像这样重构你的代码,所以它不那么拥挤,而且只有一个返回点(所以控制流更容易检查)。

    def _get_handler_by_topic_arn(topic_arn: str, event_name: str, event_message: dict):
        ret_value = None
        
        # Give a better name to conds
        cond1 = topic_arn == CONFIG.get("MT_MAIN_SNS_TOPIC_ARN")
        cond2 = topic_arn == CONFIG.get("FOX_REQUEST_SNS_TOPIC_ARN")
        cond3 = topic_arn == CONFIG.get("FOX_ORDER_RESULTS_SNS_TOPIC_ARN")
        cond4 = event_message.get("status") and event_message.get("status") != "CANCELLED"
        
        if cond1:
            ret_value = MT_MAIN_TOPIC_HANDLERS.get(event_name)
        elif cond2:
            ret_value = FOX_REQUEST_TOPIC_HANDLERS.get(event_name)
        elif cond3:
            if cond4:
                ret_value = None
            else:
                ret_value = FOX_ORDER_RESULTS_TOPIC_HANDLERS.get(event_name)
        
        return ret_value
    

    【讨论】:

    • 我也喜欢这种方法。有很多方法可以做到这一点。
    【解决方案2】:

    你也可以做类似的事情

    topics = {
        "MT_MAIN_SNS_TOPIC_ARN" : MT_MAIN_TOPIC_HANDLERS,
        "FOX_REQUEST_SNS_TOPIC_ARN" : FOX_REQUEST_TOPIC_HANDLERS,
        "FOX_ORDER_RESULTS_SNS_TOPIC_ARN" : FOX_ORDER_RESULTS_TOPIC_HANDLERS
    }
    
    def _get_handler_by_topic_arn(topic_arn: str, event_name: str, event_message: dict):
        for k,v in topics.items():
            if topic_arn == CONFIG.get(k):
                return v.get(event_name)
    

    【讨论】:

      【解决方案3】:

      你可以使用一个字典避免ifs:

      def _get_handler_by_topic_arn(topic_arn: str, event_name: str, event_message: dict):
          not_canceled = event_message.get("status") and event_message.get("status") != "CANCELLED"
      
          handlers = {
              CONFIG.get("MT_MAIN_SNS_TOPIC_ARN"): MT_MAIN_TOPIC_HANDLERS.get(event_name),
              CONFIG.get("FOX_REQUEST_SNS_TOPIC_ARN"): FOX_REQUEST_TOPIC_HANDLERS.get(event_name),
              CONFIG.get("FOX_ORDER_RESULTS_SNS_TOPIC_ARN"): None if not_canceled else FOX_ORDER_RESULTS_TOPIC_HANDLERS.get(event_name)
          }
      
          return handlers.get(topic_arn)
      

      由于如果状态不是CANCELLED,该函数也可以返回None,因此字典在设置键CONFIG.get("FOX_ORDER_RESULTS_SNS_TOPIC_ARN") 的值时会考虑到这一点。

      此外,如果topic_arn 不存在,您可以自定义将返回的内容。为此,只需将默认返回值传递给handlers.get(topic_arn),如下所示:

      handlers.get(topic_arn, "NOT FOUND")
      

      【讨论】:

        【解决方案4】:

        这是一种使用handler 映射和validator 映射的方法,可将验证逻辑与处理逻辑分离:

        HANDLER_MAP = {
            CONFIG.get("MT_MAIN_SNS_TOPIC_ARN"): MT_MAIN_TOPIC_HANDLERS,
            CONFIG.get("FOX_REQUEST_SNS_TOPIC_ARN"): FOX_REQUEST_TOPIC_HANDLERS,
            CONFIG.get("FOX_ORDER_RESULTS_SNS_TOPIC_ARN"): FOX_ORDER_RESULTS_TOPIC_HANDLERS
        }
        
        VALIDATOR_MAP = {
            CONFIG.get("FOX_ORDER_RESULTS_SNS_TOPIC_ARN"): lambda message: message.get("status") != "CANCELLED"
        }
        
        def get_handler_and_validator(topic_arn: str) -> tuple[dict, Callable]:
            handler = HANDLER_MAP.get(topic_arn, {})
            validator = VALIDATOR_MAP.get(topic_arn, lambda _: True)
            return handler, validator
        
        def _get_handler_by_topic_arn(topic_arn: str, event_name: str, event_message: dict):
            topic_handler, validator = get_handler_and_validator(topic_arn)
            if validator(event_message):
                return topic_handler.get(event_name)
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-04
          • 2013-08-08
          • 1970-01-01
          • 1970-01-01
          • 2022-01-22
          • 1970-01-01
          • 2020-07-05
          • 1970-01-01
          相关资源
          最近更新 更多