Python:如果前一个函数没有返回任何值,那么运行级联函数的最干净方法

2024-10-02 04:23:46 发布

您现在位置:Python中文网/ 问答频道 /正文

基本上,我有3个独立的函数。我想首先运行geopy_parse,如果它返回None,那么我将运行libpostal_parse,如果它返回None,我将最终运行最后一个函数google_maps_parse。函数的最终返回应该是运行的最后一个子函数的结果。我已经创建了一个函数来实现这一点,但我想用一种更干净、更具python风格的方式来重写它

代码示例:

def parse_address(address_str):
    # if no address string provided, return None result
    if not address_str:
        return (None, None, None)
    
    # execute geopy parser
    res = geopy_parse(address_str)
    
    if not res:
        res = libpostal_parse(address_str)
    if not res:
        res = google_maps_parse(address_str)
    
    return {
        'nation': res['country'],
        'state': res['state'],
        'city': res['city'] or res['town'] or res['county']
        } 

Tags: 函数nonecityreturnifparseaddressgoogle
2条回答

假设None是函数唯一可能的错误输出,您可以将它们视为布尔ish并使用or进行回退,例如

res = geopy_parse(address_str) or libpostal_parse(address_str) or google_maps_parse(address_str)

将返回第一个非虚假结果

您也可以使用next()以获得更大的灵活性,但这有点复杂,因为您必须在将iterable馈送到下一个之前过滤掉falsy值,例如

res = next(filter(None, (
    fn(address_str)
    for fn in [geopy_parse, libpostal_parse, google_maps_parse]
)), None) 

filter(None, iterable)filter(lambda a: a, iterable)等效,但比filter(lambda a: a, iterable)更有效,它将从iterable(lazy)中删除所有错误项

因此,它将函数作为输入,尝试将每个函数应用于输入,只保留真实结果,然后返回第一个这样的结果(这就是next()所做的)

因为它只使用惰性构造(生成器和过滤器),所以它只在前面的构造都不合适的情况下计算函数

对于如何简化这一点,一个很好的提示是确定您有重复的代码。您还可以利用python支持一级函数的事实(即,它们可以作为值/参数传递到其他地方)

编辑我刚看到你的变化。与一堆if语句相比,这种方法的一个好处是,如果您想添加更多解析器,它可以很容易地进行扩展

def parse_address(address_str):
    # if no address string provided, return None result
    if not address_str:
        return (None, None, None)
    
    func_list = [geopy_parse, libpostal_parse, google_maps_parse]

    for func in func_list:
        res = func(address_str)

        # The return statement immediately breaks out of the loop
        # I.e. if the first func returns a non-None value, the others don't get executed
        if res is not None:
            return {
                'nation': res['country'],
                'state': res['state'],
                'city': res['city'] or res['town'] or res['county']
            }
    else:
        # Handles the situation where all of your parsers return None
        return (None, None, None)

相关问题 更多 >

    热门问题