为什么mypy无法理解这个对象的实例化?

6
我试图定义一个类,它将另一个类作为属性_model,并将实例化该类的对象。
from abc import ABC
from typing import Generic, TypeVar, Any, ClassVar, Type

Item = TypeVar("Item", bound=Any)


class SomeClass(Generic[Item], ABC):
    _model: ClassVar[Type[Item]]

    def _compose_item(self, **attrs: Any) -> Item:
        return self._model(**attrs)

我认为self._model(**attrs)返回的是一个Item实例,因为_model明确声明为Type[Item]attrs声明为Dict[str, Any]

但是我从mypy 0.910得到的信息是:

test.py: note: In member "_compose_item" of class "SomeClass":
test.py:11: error: Returning Any from function declared to return "Item"
            return self._model(**attrs)
            ^

我做错了什么?


1
你知道 **attrs: Any 几乎失去了所有类型安全性吗?这与Alex的回答有关:Item__init__ 可以具有任何签名。你考虑过更具体的方式,例如使用 Callable[[int, str, bool], Item](带有适当的参数类型)吗? - joel
1
这个 bound=Any 真的没有任何意义... 它根本不应该有一个边界。Any 是一种特殊类型,基本上意味着“不要对此进行类型检查”。我甚至认为它并没有定义为 TypeVar 的边界应该如何工作。 - juanpa.arrivillaga
@juanpa.arrivillaga 只有在使用 --strict 设置运行 MyPy 时才会出现错误(即使您没有为 TypeVar 指定 bound=Any,我同意这是毫无意义的)。https://mypy-play.net/?mypy=latest&python=3.10&flags=strict&gist=15af7faff026f30f18b411ac099ff478 - Alex Waygood
1
@AlexWaygood,如果你将其删除,则会出现完全不同的错误。 - juanpa.arrivillaga
@juanpa.arrivillaga 是的,那是一个很好的观点! - Alex Waygood
显示剩余6条评论
1个回答

5

MyPy有时对类的类型感到有些困惑。如果您将_model指定为Callable[..., Item],而不是Type[Item](毕竟这不是一个谎言),您可以解决这个问题

from abc import ABC
from typing import Generic, TypeVar, Any, ClassVar, Callable

Item = TypeVar("Item")


class SomeClass(Generic[Item], ABC):
    _model: ClassVar[Callable[..., Item]]

    def _compose_item(self, **attrs: Any) -> Item:
        return self._model(**attrs)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接