访问嵌套属性

时间:2016-10-25 07:33:33

标签: python attributes

我目前正在实现一个ORM,它存储在由PyXB生成的DOM处理的XSD中定义的数据。 许多相应的元素包含子元素等,每个子元素都具有minOccurs=0,因此可以在DOM中解析为None。 因此,当访问包含可选元素的某个元素层次结构时,我现在面临的问题是否使用:

with suppress(AttributeError):
    wanted_subelement = root.subelement.sub_subelement.wanted_subelement

或者更确切地说

if root.subelement is not None:
    if root.subelement.sub_subelement is not None:
        wanted_subelement = root.subelement.sub_subelement.wanted_subelement

虽然这两种款式都很完美,但这更好吗? (我不是荷兰人,顺便说一句。)

2 个答案:

答案 0 :(得分:1)

这也有效:

if root.subelement and root.subelement.sub_subelement:
    wanted_subelement = root.subelement.sub_subelement.wanted_subelement

if语句将None评估为False,并将从左到右进行检查。因此,如果第一个元素的计算结果为false,则不会尝试访问第二个元素。

答案 1 :(得分:1)

如果要执行相当多的此类查找,最好将其包装在更通用的查找函数中:

# use a sentinel object distinct from None 
# in case None is a valid value for an attribute
notfound = object()

# resolve a python attribute path
# - mostly, a `getattr` that supports
#   arbitrary sub-attributes lookups    
def resolve(element, path):
    parts = path.split(".")
    while parts:
       next, parts = parts[0], parts[1:]
       element = getattr(element, next, notfound)
       if element is notfound:
           break
    return element

# just to test the whole thing    
class Element(object):
   def __init__(self, name, **attribs):
       self.name = name
       for k, v in attribs.items():
           setattr(self, k, v)

e  = Element(
    "top",
    sub1=Element("sub1"),
    nested1=Element(
        "nested1", 
        nested2=Element(
            "nested2", 
             nested3=Element("nested3")
             )
        )
    )


tests = [
    "notthere",
    "does.not.exists",
    "sub1",
    "sub1.sub2",
    "nested1",
    "nested1.nested2",
    "nested1.nested2.nested3"
    ]

for path in tests:
    sub = resolve(e, path)
    if sub is notfound:
        print "%s : not found" % path
    else:
        print "%s : %s" % (path, sub.name)