【问题标题】:Why won't mypy understand this object instantiation?为什么 mypy 不理解这个对象实例化?
【发布时间】:2021-11-19 04:24:03
【问题描述】:

我正在尝试定义一个将另一个类作为属性_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)
            ^

我做错了什么?

【问题讨论】:

  • 你知道**attrs: Any 正在失去几乎所有的类型安全吗?这与亚历克斯的回答有关:Item__init__ 可以有任何签名。您是否考虑过更具体,例如使用Callable[[int, str, bool], Item](使用适当的参数类型)?
  • 这个:bound=Any 真的没有任何意义......它应该没有界限。 Any 是一种特殊类型,基本上意味着“不要输入检查这个”。我认为它甚至没有定义它应该如何作为 TypeVar 的边界。
  • 另外,您使用的是什么版本的 mypy?在我的机器上,mypy 0.910 实际上并没有抱怨……但正如我所说,我认为 Item = TypeVar("Item", bound=Any) 的定义并不明确
  • @juanpa.arrivillaga 只有在使用 --strict 设置运行 MyPy 时才会出现错误(即使你没有为 TypeVar 指定 bound=Any,我也会得到它同意是没有意义的)。 mypy-play.net/…
  • @AlexWaygood 好吧,如果你删除它,你会得到一个完全不同的错误。

标签: python type-hinting mypy python-typing abstract-base-class


【解决方案1】:

MyPy 有时可能对类的类型有点好笑。您可以通过将_model 指定为Callable[..., Item](毕竟不是谎言)而不是Type[Item]solve this

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 2021-10-15
    • 2019-07-16
    • 2011-04-10
    相关资源
    最近更新 更多