检查xml ElementTree节点是否为None/False

9 投票
3 回答
17474 浏览
提问于 2025-04-18 06:16

我想知道,检查一个变量 myvar 是否不是 None 值,直接这样做是否安全:

if myvar:
    print('Not None detected')

我之所以问这个,是因为我有一个变量,我是通过 if variable: 来检查这个变量是否不是 None,但是这个检查一直失败。这个变量里面确实有一些数据,但在 if 的检查中却被判断为 False。

完整代码:

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

3 个回答

2

在你的情况下,这是安全的,因为 ElementTree会对 __nonzero__ 测试返回 False,这是用来检查元素是否被找到

不过,正如文档所说,如果你只想检查元素是否没有被找到,最好明确地使用 is None 来检查:

注意:因为Element对象没有定义 nonzero() 方法,所以没有子元素的元素会被测试为False。

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"

提醒一下, object.__nonzero__ 是用来进行值测试和 bool() 操作的。

3

ElementTree 对于没有子节点的元素的处理方式,跟一般的 Python 习惯有些不同。通常情况下,你可以直接在 if 条件中使用变量,并且可以相信它的布尔值是合理的。但在这个情况下,正如你亲身经历的那样,你需要做一个更明确的检查。

7

在Python中,一个对象的布尔值(也就是真假值)并不一定等于它是否是None。这个假设的正确性取决于你的对象是否定义了合适的方法。以Python 2.7为例:

object.__nonzero__(self)

这个方法用于实现真假值的测试和内置的bool()操作;它应该返回FalseTrue,或者它们的整数对应值01。如果这个方法没有定义,Python会调用__len__()(如果它被定义了),如果返回值不为零,那么这个对象就被认为是真。假如一个类既没有定义__len__()也没有定义__nonzero__(),那么它的所有实例都会被认为是真。

另外,建议你看看PEP 8,它对这个问题提供了一些指导(我强调的部分):

与单例(比如None)的比较应该始终使用isis not,而不是使用等于运算符。

而且,要小心在写if x时,实际上你想表达的是if x is not None——例如,当你在测试一个默认值为None的变量或参数是否被设置为其他值时。那个其他值可能有一种类型(比如容器),在布尔上下文中可能会被认为是假的!

因此,为了安全地测试你是否得到了Nonenot None,你应该特别使用:

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

xml.etree.ElementTree.Element的情况下,布尔值的评估与对象是否为None的语义是不同的:

供参考:

撰写回答