我想从 Pydantic BaseModel 类创建一个类型化的 DataFrame,我们将其称为具有可选字段的 MyModel。当我创建 MyModel 的多个实例时,有些实例将具有带有 None 值的可选字段,如果我使用此类行初始化 DataFrame,它们可能会具有不一致的列 dtypes。因此我想将
Optional[TypeX]
转换为 TypeX
,例如:
import pydantic
import pandas as pd
import numpy as np
from typing import Optional
class MyModel(pydantic.BaseModel):
thisfield: int
thatfield: Optional[str]
...
col_types = {kk: ff.annotation for kk, ff in MyModel.model_fields.items()}
pd.DataFrame(np.empty(0, dtype=[tuple(tt) for tt in col_types.items()]))
失败并显示
TypeError: Cannot interpret 'typing.Optional[str]' as a data type
。
我需要一个
Optional[X] -> X
的函数或方法。除了将 repr
与正则表达式一起使用之外,还有什么建议吗?
从 Python 3.10 开始,
Optional[X]
相当于 Union[X, None]
:
from typing import Union, get_args, get_origin
def get_optional_arg(typ: type) -> type | None:
# make sure typ is really Optional[...], otherwise return None
if get_origin(typ) is Union:
args = get_args(typ)
if len(args) == 2 and args[1] is type(None):
return args[0]
col_types = {
k: get_optional_arg(f.annotation) or f.annotation
for k, f in MyModel.model_fields.items()
}