如何在 Python 中创建用户定义的类型断言?
How to create a user-defined type assertion in 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
构造或其他类型构造的情况下,这将非常有用。
Mypy 通常只理解几种缩小类型的特定方法,例如使用 isinstance
或 if x is not None
。但是,在 Python >=3.10 中,PEP 647 通过新的 typing.TypeGuard
功能提供了解决此问题的方法。现在,您可以像这样编写 ComplexTypeAssertion
函数,类型检查器将理解 data
保证是 list[str]
类型,如果函数 returns 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
也可通过半官方 typing-extensions
library on PyPI 用于 Python <3.10,它为 Python 的早期版本提供了较新类型结构的反向移植。 (如果你正在使用 Mypy,你会发现 typing-extensions
已经是 Mypy 的依赖项,所以从 typing-extensions
导入一些东西甚至不一定意味着你必须添加额外的依赖项到你的项目。)
如何创建一个以类似于 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
构造或其他类型构造的情况下,这将非常有用。
Mypy 通常只理解几种缩小类型的特定方法,例如使用 isinstance
或 if x is not None
。但是,在 Python >=3.10 中,PEP 647 通过新的 typing.TypeGuard
功能提供了解决此问题的方法。现在,您可以像这样编写 ComplexTypeAssertion
函数,类型检查器将理解 data
保证是 list[str]
类型,如果函数 returns 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
也可通过半官方 typing-extensions
library on PyPI 用于 Python <3.10,它为 Python 的早期版本提供了较新类型结构的反向移植。 (如果你正在使用 Mypy,你会发现 typing-extensions
已经是 Mypy 的依赖项,所以从 typing-extensions
导入一些东西甚至不一定意味着你必须添加额外的依赖项到你的项目。)