最符合Python风格的递归应用函数到字符串值的方法

2024-09-26 04:55:21 发布

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

问题: 我在想,在不预先知道对象的模式的情况下,递归地将函数应用于对象中的字符串值的最python方法是什么?最好以足够通用的方式使其成为其他类型操作的可重用组件。在

上下文: 我正在处理一个json字符串作为api请求的输入,使用json.loads()要加载它,在应用验证之前,我想去掉对象中任何字符串前后的空白。我希望这段代码是自适应的,这样模式中的更改不会破坏它。在

当前解决方案:

def strip(obj):
    return obj.strip()

def recurse_into(obj, baseaction, basetype=str):
    if isinstance(obj, basetype):
        return baseaction(obj)
    elif isinstance(obj, list):
        return [recurse_into(o, baseaction, basetype) for o in obj]
    elif isinstance(obj, tuple):
        return tuple(recurse_into(o, baseaction, basetype) for o in obj)
    elif isinstance(obj, dict):
        return dict((k, recurse_into(v, baseaction, basetype)) 
                    for (k, v) in obj.items())
    else:
        return obj

def generate_recurse(baseaction, basetype=str):
    def f(obj):
        return recurse_into(obj, baseaction, basetype)
    return f

def recursive_strip_whitespace(obj):
    clean_whitespace = generate_recurse(strip)
    return clean_whitespace(obj)

当前解决方案的问题: 它看起来非常简洁,很难理解那些没有写这篇文章的人是怎么回事,我真的希望有更具可读性的方法来做到这一点。或者说实话这是最好的吗?在


Tags: 对象字符串inobjforreturndefisinstance
2条回答

我的建议是减少一些冗余代码:

def strip(obj):
    return obj.strip()

def recurse_into(obj, baseaction, basetype=str):
    if isinstance(obj, basetype):
        return baseaction(obj)
    elif isinstance(obj, list):
        return [recurse_into(o, baseaction, basetype) for o in obj]
    elif isinstance(obj, tuple):
        return tuple(recurse_into(o, baseaction, basetype) for o in obj)
    elif isinstance(obj, dict):
        return dict((k, recurse_into(v, baseaction, basetype)) 
                    for (k, v) in obj.items())
    return obj

def recursive_strip_whitespace(obj):
    return recurse_into(obj, strip)

同样的“反向”方法是将案例分成不同的功能,并将它们映射出来。它没有那么神奇,但看起来更具可读性。在

def strip_obj(obj):
    return obj.strip()
def strip_tuple(tuple):
    return tuple(recurse(obj) for obj in tupl)
...
def recurse(root):
    actions = {basetype: strip_obj,
              tuple: strip_tuple,
              ...}
    return actions[type(root)](root)

请注意,对于iterables,您可以使用map进行“功能化”,但我个人认为它过于密集。类似地,您可以通过在这些actions值中使用lambda来获得您的元juju,但同样地,它对于可读性来说并不是很好。在

相关问题 更多 >