Python 多级泛型是否会丢失类型信息?

发布于 2025-01-11 03:52:40 字数 943 浏览 0 评论 0原文

我使用类型注释让我的 IDE PyCharm 为我提供自动完成和类型检查功能。

对于我当前的项目,我构建了一个多级通用类层次结构,但是,在某些时候,某些类型信息似乎丢失了。
我不确定这是否是我的错、Python 类型注释/泛型机制的问题、IDE 的问题或预期行为的问题。

让我用一个简短的例子来解释这一点:

L = TypeVar("L")
class List(Generic[L]):
    # rather generic list implementation
    def get(self) -> L:
        return None


T = TypeVar("T")
class ListList(Generic[T], List[list[T]]):
    # generic implementation of a list of lists
    pass


class A(ListList[str]):
    # actual implementation of a list of lists of a specific type
    pass


ll = A()
l = ll.get()
e = l[0]

这里,pycharm 将 l 的类型显示为 list[T] ,将 e 的类型显示为 <代码>T
而我希望它分别是 list[str]str

我是否使用了泛型错误,这种行为是 python 的类型/泛型机制中的错误,是 pyCharm IDE 中的错误还是这是预期的行为?

如果是有意的,有人可以解释其背后的原因,或者指出我这样的解释吗?

不管这个原因是什么,任何人都可以告诉我一种方法,如何让 pycharm 正确识别 l 和 e 的类型,从而为我提供有用的自动完成和类似的东西。

I use Type Annotations to allow my IDE PyCharm to provide me with autocomplete and typechecking.

For my current project i built a multi-level generic class hierarchy, however, at some point, some of the type information seems to get lost.
I am not sure if this is my fault, a problem of the python type annotation/generics mechanisms, a problem of the IDE or intended behaviour.

Let me explain this with a short example:

L = TypeVar("L")
class List(Generic[L]):
    # rather generic list implementation
    def get(self) -> L:
        return None


T = TypeVar("T")
class ListList(Generic[T], List[list[T]]):
    # generic implementation of a list of lists
    pass


class A(ListList[str]):
    # actual implementation of a list of lists of a specific type
    pass


ll = A()
l = ll.get()
e = l[0]

Here, pycharm shows the type of l as list[T] and the type of e as T
whereas i would expect it to be list[str] and str respectively.

Am I using the Generics wrong, is this behaviour a bug in the typing/generics mechanism of python, a bug in the pyCharm IDE or is this intended behaviour?

If it is intended, can someone explain the reasons behind it, or point me to such explanations?

And regardless of the cause of this, can anyone show me a way how to make pycharm recognise the types of l and e correctly and thus provide me with useful autocomplete and stuff like that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别念他 2025-01-18 03:52:40

此行为似乎是一个错误:https://youtrack.jetbrains.com/issue/PY- 53082

使用 mypy 的reveal_type 确认您期望的类型是正确的。

ll = A()
l = ll.get()
e = l[0]
reveal_type(l)
reveal_type(e)
$ mypy sample.py 
sample.py:7: error: Incompatible return value type (got "None", expected "L")
sample.py:24: note: Revealed type is "builtins.list*[builtins.str*]"
sample.py:25: note: Revealed type is "builtins.str*"

在紧要关头,您可以指定创建变量的正确类型。

ll = A()
l: list[str] = ll.get()

This behavior appears to be a bug: https://youtrack.jetbrains.com/issue/PY-53082

Using mypy's reveal_type on the last line confirms the type you expected is correct.

ll = A()
l = ll.get()
e = l[0]
reveal_type(l)
reveal_type(e)
$ mypy sample.py 
sample.py:7: error: Incompatible return value type (got "None", expected "L")
sample.py:24: note: Revealed type is "builtins.list*[builtins.str*]"
sample.py:25: note: Revealed type is "builtins.str*"

In a pinch you can specify the correct type where the variable is created.

ll = A()
l: list[str] = ll.get()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文