2 回答

TA貢獻(xiàn)1780條經(jīng)驗 獲得超4個贊
通常什么時候事物會轉(zhuǎn)換為真/假?
您真正要問的問題是“當(dāng)您將列表或字典轉(zhuǎn)換為布爾值時會發(fā)生什么?”。這是因為if x:
和 的assert x
行為與您編寫if bool(x):
或時的行為相同assert bool(x)
。(順便說一句,在這些地方進(jìn)行顯式調(diào)用bool()
是不好的形式,因為它是多余的。)
答案是,如果列表和字典(以及字符串和其他容器)不為空,則True
轉(zhuǎn)換為。相反,如果它們?yōu)?em>空,則它們會被轉(zhuǎn)換為。bool
False
bool
經(jīng)常使用的術(shù)語是非空容器是“真”,空容器是“假”。
這有一個有趣的結(jié)果,bool("False")
計算結(jié)果為True
- 因為"False"
是一個非空字符串!
除了容器之外,還有一些其他常見情況:如果數(shù)字非零,則數(shù)字為真(即 和27
為0.5
真,0
而 和0.0
為假),并且值None
是假。
如何查找其他課程
我如何檢查這種行為的內(nèi)部機(jī)制?
如上所述,任何足夠像集合的東西當(dāng)它非空時都是真實的;通常測試它是否“像一個容器”是你是否可以len(x)
成功調(diào)用它,在這種情況下,只要len(x)
非零,它就是 true。
即使類不是容器(或數(shù)字),它仍然可能有一些有意義的轉(zhuǎn)換為bool()
.?事實上,您甚至可以通過定義__bool__()
方法在您自己的類上定義它。確定這一點的唯一方法是查看您正在使用的庫的文檔,而不是查看源代碼。
如果庫沒有定義此類轉(zhuǎn)換,則將bool(x)
始終返回(這是未定義或方法True
的類的默認(rèn)值)。
ElementTree具體
xml.etree.ElementTree
特別是,不幸的是,事情有點令人困惑。A 看起來有點像元素的容器:e[0]
返回第一個子元素,for child in e
返回所有子元素,并len(e)
返回子元素的計數(shù)(這些都記錄在官方文檔中)。因此,bool(e)
當(dāng)至少有一個子元素時,這一點就完全合理了——這與 Python 的其余部分的工作方式相符。然而,正如 Tomerikoo 的答案在源代碼中所示,雖然目前有效,但它已被棄用,并且將來可能不起作用。文檔也提到了這一點,但它被極度隱藏了:
注意:沒有子元素的元素將測試為
False
。此行為將在未來版本中改變。使用特定len(elem)
或elem is None
測試來代替。
下面的代碼片段解釋了這背后令人困惑的邏輯。背景是,找到namemaybe_child = e.find("child")
的子元素,或者如果沒有找到這樣的元素。但是是錯誤的,因此很容易通過寫入來檢查此搜索是否成功- 但這實際上會被視為找到了子元素但本身沒有子元素。這是文檔中的片段:e
"child"
None
None
if maybe_child:
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")

TA貢獻(xiàn)1847條經(jīng)驗 獲得超11個贊
來自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 []應(yīng)該了解失敗的原因。assert xml_element