具有不同类型的序列中的特殊属性 - 错误:"object"没有属性"__name__";也许"__ne__"或"__new__"?



我想使用一个同时具有EnumEnum成员的集合。但是,当我尝试访问特殊属性__name__时,我找不到一种不会导致mypy错误的方法来编写它。(请参阅__name__何时可以是预期类型和成员的列表。(

关于上下文,BDFL在mypy第3728期中给出了关于发生了什么的简短解释。基本上,当您对具有不同类型项的集合进行迭代时,它们是联接的。因此,在下一个例子中,mypy所说的是Enum和Enum成员连接到object。。。

示例1:

from enum import Enum
from typing import Type
class Color(Enum):
RED = 1
my_collection: tuple[Type[Color], Color] = (Color, Color.RED)
for item in my_collection:
if item is Color:
print(item.__name__)

mypy给出错误:

错误:"对象";没有属性"__名称__";;也许"__ne__";或"__new__"?

示例2:

接下来,我试图在for循环中注释变量,看看mypy错误是否获得了更多的颜色。。。

from enum import Enum
from typing import Type, Union
class Color(Enum):
RED = 1
my_collection: tuple[Type[Color], Color] = (Color, Color.RED)
item: Union[Type[Color], Color]
for item in my_collection:
if item is Color:
print(item.__name__)

这一次mypy给出了两个错误,第一个是由for循环中不兼容的类型引起的(有道理(,第二个是可预期的错误,表示Enum成员没有__name__特殊属性。

错误:赋值中的类型不兼容(表达式的类型为"object",变量的类型为Union[type[Color],Color]"(

错误:项目";颜色";的";Union[Type[Color];没有属性"__名称__">

示例3:

我的下一步是在使用__name__之前尝试键入.cast,这通常足以让mypy限制类型。。。

from enum import Enum
from typing import Type, cast
class Color(Enum):
RED = 1
my_collection: tuple[Type[Color], Color] = (Color, Color.RED)
for item in my_collection:
if item is Color:
item = cast(Type[Color], item)
print(item.__name__)

这次的错误是:

错误:没有属性&quot__名称__"

这3个例子在运行时可以工作,但是Python对具有不同类型项的集合进行迭代的方式是什么?这些项不会导致mypy错误?(使用默认配置的Python 3.9和mypy 0.812。(

我查看了MyPy的GitHub上的几个问题,学到了两件事:

根据Guido的说法,
  1. <nothing>不应显示在输出中
  2. <nothing>意味着MyPy union’ed the types(对于item,它是Type[Color]Color(,结果为nothing(即"空集"(,因此它键入nothing。换句话说,MyPy在强制转换后无法计算item的有用类型,请参阅:
    reveal_type(my_collection[0])
    reveal_type(my_collection[1])
    for item in my_collection:
    if item is Color:
    reveal_type(item)
    item = cast(Type[Color], item)
    reveal_type(item)
    print(item.__name__)
    
    $ mypy -V; mypy so70636782.py
    mypy 0.931
    so70636782.py:9: note: Revealed type is "Type[so70636782.Color]"
    so70636782.py:10: note: Revealed type is "so70636782.Color"
    so70636782.py:13: note: Revealed type is "builtins.object"
    so70636782.py:15: note: Revealed type is "<nothing>"
    so70636782.py:16: error: <nothing> has no attribute "__name__"
    Found 1 error in 1 file (checked 1 source file)
    
    我认为你达到了工具的极限。你可以在GitHub上发布一个问题

MyPy在我的经验中对并集不是很好,所以我建议你只使用元组是类型对的事实:

color_class, color = my_collection  # unpacking
print(color_class.__name__)

通过这种方式,MyPy可以单独跟踪每个变量,每个变量都有一个类型。

最新更新