猿问

为什么对空列表/字典的断言失败?

assert {}

失败并显示AssertionError.


导致这个问题的问题如下:


import xml.etree.ElementTree as ET


xml_element = ET.Element("tag")


assert xml_element

也失败了AssertionError。


assert评估expression,我明白了。


还;


if []:

    print("foo")

不会打印任何内容,因为返回空列表,False但是,


if [1]:

    print("foo")

会打印 foo.


我的问题是我如何检查这种行为的内部机制?


斯蒂芬大帝
浏览 137回答 2
2回答

Helenr

通常什么时候事物会转换为真/假?您真正要问的问题是“当您将列表或字典转换为布尔值时会发生什么?”。这是因为if x:和 的assert x行为与您编写if bool(x):或时的行为相同assert bool(x)。(顺便说一句,在这些地方进行显式调用bool()是不好的形式,因为它是多余的。)答案是,如果列表和字典(以及字符串和其他容器)不为空,则True转换为。相反,如果它们为空,则它们会被转换为。boolFalsebool经常使用的术语是非空容器是“真”,空容器是“假”。这有一个有趣的结果,bool("False")计算结果为True- 因为"False"是一个非空字符串!除了容器之外,还有一些其他常见情况:如果数字非零,则数字为真(即 和27为0.5真,0而 和0.0为假),并且值None是假。如何查找其他课程我如何检查这种行为的内部机制?如上所述,任何足够像集合的东西当它非空时都是真实的;通常测试它是否“像一个容器”是你是否可以len(x)成功调用它,在这种情况下,只要len(x)非零,它就是 true。即使类不是容器(或数字),它仍然可能有一些有意义的转换为bool(). 事实上,您甚至可以通过定义__bool__()方法在您自己的类上定义它。确定这一点的唯一方法是查看您正在使用的库的文档,而不是查看源代码。如果库没有定义此类转换,则将bool(x)始终返回(这是未定义或方法True的类的默认值)。ElementTree具体xml.etree.ElementTree特别是,不幸的是,事情有点令人困惑。A 看起来有点像元素的容器:e[0]返回第一个子元素,for child in e返回所有子元素,并len(e)返回子元素的计数(这些都记录在官方文档中)。因此,bool(e)当至少有一个子元素时,这一点就完全合理了——这与 Python 的其余部分的工作方式相符。然而,正如 Tomerikoo 的答案在源代码中所示,虽然目前有效,但它已被弃用,并且将来可能不起作用。文档也提到了这一点,但它被极度隐藏了:注意:没有子元素的元素将测试为False。此行为将在未来版本中改变。使用特定len(elem)或elem is None测试来代替。下面的代码片段解释了这背后令人困惑的逻辑。背景是,找到namemaybe_child = e.find("child")的子元素,或者如果没有找到这样的元素。但是是错误的,因此很容易通过写入来检查此搜索是否成功- 但这实际上会被视为找到了子元素但本身没有子元素。这是文档中的片段:e"child"NoneNoneif maybe_child:Falseelement = root.find('foo')if not element:  # careful!    print("element not found, or element has no subelements")if element is None:    print("element not found")

回首忆惘然

来自ElementTree的源代码(属于 类Element):class Element:[...]    def __init__(self, tag, attrib={}, **extra):        if not isinstance(attrib, dict):            raise TypeError("attrib must be dict, not %s" % (                attrib.__class__.__name__,))        self.tag = tag        self.attrib = {**attrib, **extra}        self._children = [][...]    def __bool__(self):        warnings.warn(            "The behavior of this method will change in future versions.  "            "Use specific 'len(elem)' or 'elem is not None' test instead.",            FutureWarning, stacklevel=2            )        return len(self._children) != 0 # emulate old behaviour, for now由于您刚刚初始化了一个新元素,因此它_children是一个空列表(如 中所示__init__),因此如果您了解失败的原因,您也assert []应该了解失败的原因。assert xml_element
随时随地看视频慕课网APP

相关分类

Python
我要回答