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

jfgube3f  于 5个月前  发布在  Python
关注(0)|答案(2)|浏览(63)

本方案:

class Array:
    def __init__(self, underlying):
        self.underlying = underlying

    def __class_getitem__(cls, key):
        return Array(key)

    def __getitem__(self, key):
        pass

    def __str__(self):
        return f"Array({self.underlying=})"

def foo(name, kind):
    pass

foo(name="x", kind=Array["int"])

字符串
mypy标记:

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)的假元类,您的示例可以通过类型检查器。

from __future__ import annotations

import typing_extensions as t

if t.TYPE_CHECKING:    
    class _ArrayMeta(type):
        def __getitem__(self, key: str, /) -> Array: ...
else:
    _ArrayMeta = type

class Array(metaclass=_ArrayMeta):
    # The rest of the code remains identical
    def __init__(self, underlying):
        self.underlying = underlying

    def __str__(self):
        return f"Array({self.underlying=})"

    def __class_getitem__(cls, key) -> Array:
        return Array(key)

def foo(name, kind):
    pass

个字符

相关问题