如何使用 dict 减少 if 语句的数量?

How to reduce number if-statements using dict?

我有以下多个案例的代码:

def _extract_property_value(selector: Selector) -> str:
    raw_value = selector.xpath("span[2]")

    default_value = raw_value.xpath("./text()").get().strip()
    value_with_a = ', '.join([value.strip() for value in raw_value.xpath("./a /text()").getall()])
    value_with_div_and_a = ', '.join([value.strip() for value in raw_value.xpath("./div /a /text()").getall()])

    if value_with_a:
        return value_with_a
    elif value_with_div_and_a:
        return value_with_div_and_a
    elif default_value:
        return default_value

我想摆脱 if 语句并尽可能简化这段代码。我不是优秀的 Pyton 开发者。我知道有模式“策略”,下面我试图实现它:

def _extract_property_value(selector: Selector) -> str:
    raw_value = selector.xpath("span[2]")
    values_dict = {
        'default value': raw_value.xpath("./text()").get().strip(),
        'value with a': ', '.join([value.strip() for value in raw_value.xpath("./a /text()").getall()]),
        'value with div and a': ', '.join([value.strip() for value in raw_value.xpath("./div /a /text()").getall()])
    }
    return [item for item in values_dict.values() if item != ''][0]

但是...现在当我想到这一点时 - 在那里使用策略是个坏主意。我不知道。有人可以帮我简化该代码吗?或者那些 if 语句是必需的。

虽然您当然可以尝试使用策略模式,但有一种更简单的方法可以做到这一点。除了 if/else 链,你可以简单地做:

return value_with_a or value_with_div_and_a or default_value

我们可以减少 if 语句的数量,但不需要字典的帮助。

有问题的代码无条件地为 3 个变量赋值。这样做之后,将检查这些变量以确定哪些变量(如果有的话)将 returned 给调用者。但是,这些变量之间没有依赖关系。因此,可以按优先级顺序处理它们,如果获取了适当的值,则可以立即 returned 从而使处理效率大大提高。

def _extract_property_value(selector):
    def f1(rv):
        return rv.xpath("./text()").get().strip()
    def f2(rv):
        return ', '.join([value.strip() for value in rv.xpath("./a /text()").getall()])
    def f3(rv):
        return ', '.join([value.strip() for value in rv.xpath("./div /a /text()").getall()])
    raw_value = selector.xpath("span[2]")
    for func in [f2, f3, f1]: # note the priority order - default last
        if (v := func(raw_value)):
            return v

如果找不到合适的值,修改后的函数将隐式 return None。在这方面,它与 OP 的原始代码没有什么不同