Почему элементы ElementTree - это falsy-объекты?
До этого момента не пользовался xml.etree, и столкнулся со странной вещью
if some_tag.find('other_tag'):
print('Я существую')
В таком виде эта конструкиця не работает и приходится делать вот так
if some_tag.find('other_tag') is not None:
print('Я существую')
Есть ли в этом какой-то глубокий смысл? Почему это реализовано так? Для чего существующий в структуре xml объект сделали falsy?
Ответы (1 шт):
Должно работать, т.к. find или вернет объект или None, если тот не был найден.
А проверка if с объектом обычно возвращает True, если тот существует, но тут есть важный момент, то, что возвращается при if some_tag.find('other_tag') зависит от магического метода __bool__ у объекта (того что find вернет).
Т.е. None в любом случае будет ассоциирован с False, а вот как будет ассоциирован объект зависит от того, что он вернет в __bool__. Поэтому, наиболее точно проверять как is not None.
PS.
Наглядно про __bool__:
class MyFalse:
pass
print(bool(MyFalse()))
if MyFalse():
print('[1]')
# True
# [1]
class MyFalse:
def __bool__(self):
return False
print(bool(MyFalse()))
if MyFalse():
print('[2]')
# False
PPS.
А так у меня не повторилось, но я вам верю:
import xml.etree.ElementTree as ET
tree = ET.fromstring("""\
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
</data>
""")
if tree.find('other_tag'):
print('Я существую / other_tag')
if tree.find('other_tag') is not None:
print('Я существую / other_tag')
if tree.find('country'):
print('Я существую / country')
if tree.find('country') is not None:
print('Я существую / country')
Результат:
Я существую / country
Я существую / country