2016-10-25 3 views
0

Ich implementiere derzeit ein ORM, das Daten speichert, die in einer XSD definiert sind, die mit einem DOM verarbeitet wird, das von PyXB generiert wird. Viele der jeweiligen Elemente enthalten Unterelemente usw., die jeweils eine minOccurs=0 haben und daher im DOM zu None aufgelöst werden können. Wenn also einige Elementhierarchie enthält optionale Elemente Zugriff auf Gesicht ich jetzt das Problem, ob zu verwenden:Beim Zugriff auf verschachtelte Attribute auf Keine prüfen

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

oder eher

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

Während beide Arten perfekt funktionieren, was bevorzugt ist? (Ich bin nicht Dutch, btw.)

Antwort

1

Dies funktioniert auch:

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

Die if-Anweisung wertet None als falsch und wird von links nach rechts überprüfen. Wenn also das erste Element zu false ausgewertet wird, wird nicht versucht, auf das zweite Element zuzugreifen.

+0

Ja, your're rechts. Auf diese Weise kann der Ausdruck jedoch leicht mehr als 80 Zeichen lang sein. –

1

Wenn Sie schon einige solche Lookups durchführen müssen, besser, dies in eine allgemeinere Lookup-Funktion einpacken:

# 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) 
+0

Ich habe tatsächlich eine Menge dieser Zugriffsprüfungen durchzuführen. Der Zugriff auf die Attribute über eine stringifizierte Version des Pfads würde meinen Code wahrscheinlich jedoch weniger lesbar und fehleranfällig machen und würde die PyXB DOM-Modelle ad absurdum führen. –

+0

@RichardNeumann für mich würde ich die "stringified path" Auflösung viel lesbarer finden als lange Zeilen von 'if elt.attr und elt.attrattr und elt.attrattrstrsubattr' etc, aber das ist möglicherweise subjektiv. Wrt/Absurdität, würde ich sagen, dass ein DOM-Modell, das Pfadausdruck-Lookups nicht unterstützt _ ist_ eine Absurdität, aber hier wieder YMMV;) –

Verwandte Themen