【问题标题】:Asking isinstance on a Union[...] type在 Union[...] 类型上询问 isinstance
【发布时间】:2022-01-14 08:18:14
【问题描述】:

我正在尝试就用户定义的类型提出isinstance 问题:ConstData = Union[int, str]

from typing import Union, Optional
ConstData = Union[int, str]
def foo(x) -> Optional[ConstData]:
    if isinstance(x, ConstData):  # <--- this doesn't work
    # if isinstance(x, (int, str)): <--- this DOES work ...
        return x
    return None

很遗憾,它不起作用:

$ mypy main.py
main.py:4: error: Parameterized generics cannot be used with class or instance checks
main.py:4: error: Argument 2 to "isinstance" has incompatible type "object"; expected "Union[type, Tuple[Union[type, Tuple[Any, ...]], ...]]"
Found 2 errors in 1 file (checked 1 source file)

有什么优雅的方法可以解决这个问题吗?

【问题讨论】:

标签: python types mypy


【解决方案1】:

关于:

“不过,if isinstance(x, get_args(ConstData)): return xmypy 无法推断出x 具有正确的返回类型。它抱怨它是Any

我认为这是reveal_type() 中的一个错误,Mypy 理解了x 类型的缩小。正如您在下面的代码中看到的,当使用x 调用test() 时,它不会引发错误:

def test(k:Union[int, str]) -> None:
    pass


def foo(x: Any) -> Optional[ConstData]:
    if isinstance(x, get_args(ConstData)):
        reveal_type(x)  # Mypy: Revealed type is "Any"
        test(x)  # Mypy: no error
        return x  # Mypy: no error
    return None

【讨论】:

  • 对不起,我错了:get_args 在此上下文中无效:如果您使用 foo(x: Optional[ConstData]) 更改 foo(x: Any) 签名,则 test(x) 显示 mypy错误:Mypy: Argument 1 to "test" has incompatible type "Union[int, str, None]"; expected "Union[int, str]"。这意味着None 类型尚未被isinstance 删除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
  • 2013-06-10
  • 1970-01-01
  • 2017-10-20
相关资源
最近更新 更多