尝试使用类型提示来执行 Python (3.8.8) 并从 mypy (0.931) 中获取我无法真正理解的错误。
import xml.etree.ElementTree as ET
tree = ET.parse('plant_catalog.xml') # read in file and parse as XML
root = tree.getroot() # get root node
for plant in root: # loop through children
if plant.find("LIGHT") and plant.find("LIGHT").text == "sun"
print("foo")
这会引发 mypy 错误
Item "None" of "Optional[Element]" has no attribute "text"
。
但为什么?我确实在 if 子句的前半部分检查了 plant.find("LIGHT")
返回 None
的可能性。如果第一部分失败,则访问 .text
属性的第二部分甚至不会执行。
如果我修改为
lights = plant.find("LIGHT")
if lights:
if lights.text == selection:
print("foo")
错误消失了。
这是因为
plant
对象在第一次检查和第二次检查之间可能仍然会发生变化吗?但是分配给变量不会自动复制内容,它仍然只是对可能更改的对象的引用。那为什么第二次就通过了呢?
(是的,我知道重复
.find()
两次也是不省时的。)
mypy
不知道 plant.find("LIGHT")
始终返回相同的值,因此它不知道您的测试是正确的防护。
所以你需要将它分配给一个变量。就 mypy 而言,变量在不重新分配的情况下无法从一个对象更改为另一个对象,并且如果不对它执行其他操作,其内容也无法更改。