python 类型Type[Array]不是泛型且不可索引

jfgube3f  于 2024-01-05  发布在  Python
关注(0)|答案(2)|浏览(171)

本方案:

  1. class Array:
  2. def __init__(self, underlying):
  3. self.underlying = underlying
  4. def __class_getitem__(cls, key):
  5. return Array(key)
  6. def __getitem__(self, key):
  7. pass
  8. def __str__(self):
  9. return f"Array({self.underlying=})"
  10. def foo(name, kind):
  11. pass
  12. foo(name="x", kind=Array["int"])

字符串
mypy标记:

  1. x.py:17: error: The type "Type[Array]" is not generic and not indexable [misc]


我添加__getitem__只是为了看看它是否能解决这个问题(它没有)。我不打算在这里使用Array作为类型(在typing的意义上),只是为了在其他地方传递数组类型的可爱语法。
这个mypy错误是什么意思,我如何修复它(最好是用# ignore注解以外的东西)?

mhd8tkvw

mhd8tkvw1#

我不打算在这里使用Array作为类型(在typing的意义上),只是为了在其他地方传递数组类型的可爱语法。
__class_getitem__仅用于输入。参见文档:

  • classmethod* object.__class_getitem__(cls, key)

返回一个对象,该对象通过在 key 中找到的类型参数表示泛型类的特殊化。
更具体地说:
不鼓励在任何类上使用__class_getitem__(),除非是为了类型提示。
所以不幸的是,看起来你想要的是不可能的。只要使用常规的构造函数语法,Array("int")
另外,以防你不知道,特殊方法不应该以非预期的方式使用:

  • 在任何上下文中使用__*__名称,如果没有明确记录使用,则会在没有警告的情况下被破坏。
btqmn9zl

btqmn9zl2#

如前所述,__class_getitem__是为泛型类型保留的,而 * 没有 * 保留的,仍然可用的是元类的__getitem__,它允许您提供相同的API。
这样,通过引入一个带有__getitem__mypy PlaygroundPyright Playground)的假元类,您的示例可以通过类型检查器。

  1. from __future__ import annotations
  2. import typing_extensions as t
  3. if t.TYPE_CHECKING:
  4. class _ArrayMeta(type):
  5. def __getitem__(self, key: str, /) -> Array: ...
  6. else:
  7. _ArrayMeta = type
  8. class Array(metaclass=_ArrayMeta):
  9. # The rest of the code remains identical
  10. def __init__(self, underlying):
  11. self.underlying = underlying
  12. def __str__(self):
  13. return f"Array({self.underlying=})"
  14. def __class_getitem__(cls, key) -> Array:
  15. return Array(key)
  16. def foo(name, kind):
  17. pass

个字符

展开查看全部

相关问题