我目前正在实现一个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
虽然这两种款式都很完美,但这更好吗? (我不是荷兰人,顺便说一句。)
答案 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)