即使我检查 None,为什么 mypy 也会标记“Item None has no attribute x”错误?

Cha*_*_99 6 python type-hinting mypy

尝试使用类型提示执行 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")
Run Code Online (Sandbox Code Playgroud)

这会引发 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")
Run Code Online (Sandbox Code Playgroud)

错误消失了。

这是因为plant对象在第一次检查和第二次检查之间仍然可能发生变化吗?但是分配给变量不会自动复制内容,它仍然只是对可能更改的对象的引用。那为什么第二次就通过了呢?

(是的,我知道重复.find()两次也不节省时间。)

Bar*_*mar 8

mypy不知道plant.find("LIGHT")总是返回相同的值,因此它不知道您的测试是适当的防护。

所以你需要将它分配给一个变量。就 mypy 而言,变量在不重新分配的情况下无法从一个对象更改为另一个对象,并且如果不对它执行某些其他操作,则其内容也无法更改。