如何在Python中创建用户定义的类型断言?

2024-09-28 17:25:10 发布

您现在位置:Python中文网/ 问答频道 /正文

如何创建一个函数,以类似于isinstance的方式缩小变量的类型(对于静态类型检查器)

例如,ComplexTypeAssertion只是在运行时缩小类型范围,但不用于静态检查:

def MyFunction(myData: object) -> object:
  if isinstance(myData, list):
    reveal_type(myData)  # Revealed type is 'builtins.list[Any]'
  if ComplexTypeAssertion(myData):   # <<< How to make MyPy understand this?
    reveal_type(myData)  # Revealed type is 'builtins.object'

def ComplexTypeAssertion(data: object) -> bool:
    return isinstance(data, list) and all(isinstance(value, str) for value in data)

我如何定义ComplexTypeAssertion以便静态分析工具能够理解该类型

显然,这是一个玩具的例子,现实生活中的例子会更复杂。在我想断言某些数据遵循TypedDict构造或其他类型构造的情况下,这将非常有用


Tags: 类型dataifobjectisdeftype静态
1条回答
网友
1楼 · 发布于 2024-09-28 17:25:10

Mypy通常只理解几种缩小类型的特定方法,例如使用isinstanceif x is not None。然而,在Python中>=3.10,PEP 647使用新的typing.TypeGuard功能提供了此问题的解决方案。现在,您可以像这样编写ComplexTypeAssertion函数,并且类型检查器将了解data保证为list[str]类型,如果函数返回True

from typing import TypeGuard

def ComplexTypeAssertion(data: object) -> TypeGuard[list[str]]:
    return isinstance(data, list) and all(isinstance(value, str) for value in data)

TypeGuard也可用于Python<;3.10通过半官方的^{} library on PyPI,它为Python的早期版本提供了新类型构造的后端口。(如果您正在使用Mypy,您会发现typing-extensions已经是Mypy的依赖项,因此从typing-extensions导入某些内容甚至不一定意味着您必须向项目添加额外的依赖项。)

相关问题 更多 >