2014-05-12 13 views
6

Czy to jest bezpieczne, aby sprawdzić, czy zmienna myvar nie-None wartość po prostu:Sprawdź, czy węzeł xml ElementTree jest None/Fałsz

if myvar: 
    print('Not None detected') 

Pytam bo mam ten zmienną i sprawdzał, czy zmienna nie była None po prostu if variable:, ale kontrola się nie udała. Zmienna zawiera niektóre dane, ale w wyniku sprawdzenia została wykonana wartość Fałsz w sprawdzeniu if.

Pełny Kod:

from xml.etree import ElementTree as ElementTree 

root = ElementTree.fromstring('Some xml string') 

parameters = root.find('Some Tag') 

udh = parameters.find('UDH') 

if udh and udh.text: # In this line the check is failing, though the udh variable has value: <Element 'UDH' at 0x7ff614337208> 
    udh = udh.text 
    # Other code 
else: 
    print('No UDH!') # Getting this output 
+0

To jest rzeczywiście błędne. '' if myvar: '' przy założeniu '' myvar'' jest '' None'' w rzeczywistości nie będzie wartościowane na '' True'' i dlatego Twoja próbka nie będzie działać. Najlepiej jednak jest użyć formularza: '' jeśli myvar nie jest Brak: '' lub '' if myvar jest Brak: '' –

+0

Zostało tu udzielone: ​​http://stackoverflow.com/questions/3965104/not-none -test-in-python – ka2m

+0

Czy twoja kontrola nie działa, ponieważ nie ma tekstu w udh? Może to być pusty węzeł XML. – Midnighter

Odpowiedz

5

W Pythonie wartość boolowska (prawda) obiektu nie musi być równa None lub nie. Poprawność tego założenia zależy od tego, czy twój obiekt prawidłowo zdefiniował poprawne metody. Jak dla Pythona 2.7:

object.__nonzero__(self)

Powołani do wdrożenia badań wartość prawdy i działanie wbudowanego bool(); powinien zwrócić False lub True lub ich całkowite odpowiedniki 0 lub 1. Gdy ta metoda nie jest zdefiniowana, wywoływana jest __len__(), jeśli jest zdefiniowana, a obiekt jest uznawany za prawdziwy, jeśli jego wynik jest niezerowy. Jeśli klasa nie definiuje ani __len__(), ani __nonzero__(), wszystkie jej wystąpienia są uznawane za prawdziwe.

Również spojrzeć na PEP 8, który zawiera wytyczne dotyczące tego zagadnienia (kopalni nacisk):

porównań singletons jak None zawsze powinny być wykonane z is lub is not nigdy operatorów równości .

Pamiętaj też o pisaniu if x, jeśli naprawdę masz na myśli - np. podczas testowania, czy zmienna lub argument domyślnie ustawiony na None został ustawiony na inną wartość. Inna wartość może mieć typ (taki jak kontener), który może być fałszem w kontekście logicznym!

Dlatego, aby bezpiecznie sprawdzić, czy masz None lub not None należy użyć specjalnie:

if myvar is None: 
    pass 
elif myvar is not None: 
    pass 

W przypadku xml.etree.ElementTree.Element semantyki logicznej oceny różnią się od None -ness obiektu:

Dla porównania:

+3

[pep 8] (http://legacy.python.org/dev/peps/pep-0008/#programming-recommendations) również ma na ten temat następujące słowo: * Zwróć też uwagę na pisanie '' if x'' kiedy naprawdę znaczy "jeśli x nie jest żadnym" '* –

+1

@ JonasWielicki dzięki za referencję! – moooeeeep

+0

Bardzo dziękuję za odpowiedź. Czy możesz powiedzieć, co dzieje się w Pythonie 3, aby ocenić, czy wartość określona przez zmienną może być typu Boolean? – giga

2

ElementTree zachowanie dla węzłów bez dzieci jest notorycznie odejście od standardowej praktyki Pythona. Ogólnie rzecz biorąc, można bezpiecznie użyć zmiennej w warunku if i założyć, że wartość logiczna jest sensowna. W takim przypadku, jak doświadczyłeś z pierwszej ręki, będziesz musiał wykonać bardziej jednoznaczny czek.

1

Twoim przypadku, jest to bezpieczne, ponieważ ElementTree returns False to the __nonzero__ testaby sprawdzić, czy element został znaleziony lub nie.

Jednak, jak mówi doc, to lepiej, aby sprawdzić jawnie, z is None jeśli chcesz tylko sprawdzić, czy element nie został znaleziony:

Uwaga: Ponieważ obiekty Element nie definiują niezerowa metoda(), elementy bez podelementów będą testowane jako Fałsz.

element = root.find('foo') 

if not element: # careful! 
    print "element not found, or element has no subelements" 

if element is None: 
    print "element not found" 

Dla przypomnienia object.__nonzero__ stosuje się w testach wartości i operacji bool().

Powiązane problemy