我的pythonic解决方案减少了getattr问题

Hel*_*nar 5 python reduce attributes getattr

我以前使用reduce和getattr函数以链式方式调用属性,如"thisattr.thatattr.blaattar"IE:

reduce(getattr, 'xattr.yattr.zattr'.split('.'), myobject)
Run Code Online (Sandbox Code Playgroud)

工作得很好,但是现在我有了新的要求,我的字符串可以调用特定数量的属性:"thisattr.thatattr [2] .blaattar"

reduce(getattr, 'xattr.yattr[2].zattr'.split('.'), myobject)
Run Code Online (Sandbox Code Playgroud)

现在它不起作用,我得到xattr object has no attribute 'yattr[2]'错误.

什么是一个优雅的解决方案,适用于任何一种方式?

问候

小智 0

您将需要

  1. 获取 xattr.yattr
  2. 获取其中的第二项
  3. 第二项,获取 zattr

正如您所看到的,这涉及两个不同的操作。reduce不能(优雅地)做到这一点。适用于两者的解决方案必须解析字符串以检测哪里需要索引访问。一个简单但脆弱(即如果喂食BS则行为未定义)的解决方案如下所示:

def extended_chain_getattr(names, obj):
    import re
    result = obj        
    for name in names.split('.'):
        name_match = re.match(r'([a-zA-Z_][a-zA-Z0-9_]*)(\[\d\])?', name)
        assert name_match is not None
        result = getattr(result, name_match.group(1))
        if len(name_match.groups()) == 2:
            index = int(name_match.group(2))
            result = result[index]
    return result
Run Code Online (Sandbox Code Playgroud)

超出了我的想象,因此未经测试。