我使用类型注释来进行一些基本的类型检查和自动类型转换。
作为其中的一部分,我希望检查给定类型是否应可分配给数据类的某些字段,即该类型是否与我的数据类上的类型注释“兼容”。
是否有任何开箱即用的方法来检查给定类型是否可分配给其他类型?IE
from typing import Optional, Union, Annotated, Type
def is_assignable(from_what: Type, to_what: Type) -> bool:
// .. how?
is_assignable(int, int) // should be true
is_assignable(int, Optional[int]) should be true
is_assignable(int, Annotated[Union[str, Optional[int]], "hello world"]) // should be true
is_assignable(float, Annotated[Union[str, Optional[int]], "hello world"]) // False. Can't assign float to Annotated[Union[str, Optional[int]], "hello world"])
Run Code Online (Sandbox Code Playgroud)
我可以尝试自己解开所有的typing.*逻辑,即解开Optional、Union、Annotated等等,但这感觉相当难看(而且不太可维护,如果在最近的python版本中添加了新的东西)。
使用 pydantic 模型而不是数据类是一种开箱即用的方法,例如:
from pydantic import BaseModel, ValidationError
class MyModel(BaseModel):
a: int
b: str
try:
x = MyModel(a=2, b="asd") # OK
except ValidationError as exc:
.... # Catch the error if any, in this case this block will not execute
try:
x = MyModel(a="asd", b=2) # Wrong types, cannot parse "asd" to int
except ValidationError as exc:
.... # Catch the error and work around it.
Run Code Online (Sandbox Code Playgroud)
请注意,类型并没有严格执行,Pydantic 实际上是一个解析库,而不是一个验证库(虽然验证、验证器等词随处可见,但实际上意思是解析)。因此,MyModel(a=2, b=3)也可以工作,因为3可以解析为 string str(3) -> "3",但是如果您愿意,您可以实现自己的更严格的验证器。