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

Kar*_*any 6 python strategy-pattern python-3.x

我有以下具有多种情况的代码:

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
Run Code Online (Sandbox Code Playgroud)

我想摆脱 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]
Run Code Online (Sandbox Code Playgroud)

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

mat*_*cja 6

虽然您当然可以尝试使用策略模式,但有一种更简单的方法可以做到这一点。您可以简单地执行以下操作,而不是 if/else 链:

return value_with_a or value_with_div_and_a or default_value
Run Code Online (Sandbox Code Playgroud)


Ctr*_*rlZ 5

我们可以减少if语句的数量,但无需借助字典。

相关代码无条件地将值分配给 3 个变量。完成此操作后,将检查这些变量以确定将哪些变量(如果有)返回给调用者。但是,这些变量之间不存在依赖关系。因此,它们可以按优先级顺序进行处理,如果获取了适当的值,则可以立即返回该值,从而使处理过程更加高效。

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
Run Code Online (Sandbox Code Playgroud)

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