使用嵌套类型键入递归函数

问题描述 投票:0回答:2

背景:解决一些算法问题

问题

我正在尝试在 VSCode 中使用嵌套类型的递归函数,它一直向我抛出错误。我把它减少到这个

from typing import Type

NestedStr = list[str | Type["NestedStr"]]


def get_first(x: str | NestedStr) -> str:
    if isinstance(x, str):
        return x
    return get_first(x[0]) # Argument of type "str | NestedStr" cannot be assigned to parameter "x" of type "str | NestedStr" in function "get_first"


assert get_first(["a", "b"]) == "a" # No error thrown here
assert get_first([["a", "b"]]) == "a" # Argument of type "list[list[str]]" cannot be assigned to parameter "x" of type "str | NestedStr" in function "get_first"

显然,当

x
不是
str
时,它应该是
NestedStr
因此它可以是一个无限嵌套列表,但 pylance 似乎不知道它。
代码可以完美运行,但错误很烦人。无论如何要压制它(除了“类型:忽略”)?

相关

附录

完整的错误信息

  • 递归调用
    get_first(x[0])
Argument of type "str | NestedStr" cannot be assigned to parameter "x" of type "str | NestedStr" in function "get_first"
  Type "str | NestedStr" cannot be assigned to type "str | NestedStr"
    Type "NestedStr" cannot be assigned to type "str | NestedStr"
      "Type[type]" is incompatible with "Type[str]"
      "Type[type]" is incompatible with "NestedStr" Pylance reportGeneralTypeIssues
  • 随叫随到
    list[list[str]]
Argument of type "list[list[str]]" cannot be assigned to parameter "x" of type "str | NestedStr" in function "get_first"
  Type "list[str]" cannot be assigned to type "str | NestedStr"
    "list[str]" is incompatible with "str"
    Type "list[str]" cannot be assigned to type "NestedStr" Pylance reportGeneralTypeIssues
python mypy python-typing pylance
2个回答
3
投票

在我看来,这个

NestedStr = list[str | Type["NestedStr"]]
必须更改为那个
NestedStr = list[str | "NestedStr"]
,因为它要么是字符串,要么是 NestedStr 的具体实例,但不是普通类型。我没有检查过 pylance,但是 mypy 接受了并且没有提出任何问题。


0
投票

Pylance v2023.3.20
@Simon Hawe 的回答会引发错误
"NestedStr" is not defined Pylance (reportUndefinedVariable)

目前的解决方案是这样的:

from typing import Union

NestedStr = list[Union[str, "NestedStr"]]


def get_first(x: str | NestedStr) -> str:
    if isinstance(x, str):
        return x
    return get_first(x[0])
    # or the shorter and working version in next line:
    # return x if isinstance(x, str) else get_first(x[0])


assert get_first([["a", "b"]]) == "a"
© www.soinside.com 2019 - 2024. All rights reserved.