如何在pydantic中使用两个变量类型.使用type.union的BaseModel ?



我需要我的模型接受字节类型变量或字符串类型变量,并在传递任何其他类型时引发异常。

from typing import Union
from pydantic import BaseModel

class MyModel(BaseModel):
a: Union[bytes, str]

m1 = MyModel(a='123')
m2 = MyModel(a=b'123')
print(type(m1.a))
print(type(m2.a))

在我的例子中,模型将字节和字符串都解释为字节。

输出:

<class 'bytes'>
<class 'bytes'>

所需输出:

<class 'str'>
<class 'bytes'>

如果我重新赋值成员a,可以实现上面期望的输出:

m1 = MyModel(a='123')
m1.a = '123'

有可能一次得到它吗?

您面临的问题是,str类型做一些自动转换(这里在文档中):

字符串按原样接受,intfloatDecimal使用str(v)强制转换,bytesbytearray使用v.decode()转换,继承自str的枚举使用v.value转换,其他所有类型都会导致错误

bytes按原样接受,bytearray使用bytes(v)转换,str使用v.encode()转换,int,floatDecimal使用str(v).encode()强制转换

您可以使用StrictTypes来避免兼容类型之间的自动转换(例如:strbytes):

from typing import Union
from pydantic import BaseModel, StrictStr, StrictBytes

class MyModel(BaseModel):
a: Union[StrictStr, StrictBytes]

m1 = MyModel(a='123')
m2 = MyModel(a=b'123')
print(type(m1.a))
print(type(m2.a))

输出将如预期:

<class 'str'>
<class 'bytes'>