pydantic学习与使用-3.Typing 类型中的 Optional 和 Union

Posted 上海-悠悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pydantic学习与使用-3.Typing 类型中的 Optional 和 Union相关的知识,希望对你有一定的参考价值。

前言

在python 函数和类中,参数声明时可以声明参数是必填类型,也可以给参数设置默认值。

函数中的参数

以下函数,参数a是必填项,b给了默认值,是可选项。

  • a参数声明为int类型
  • b参数声明为int类型,并给了默认值1
  • -> int 是声明函数返回值是int类型
def fuc1(a: int, b: int = 1) -> int:
    print('a+b的值为:', a+b)
    return a+b


if __name__ == '__main__':
    fuc1(2)

如果我们想给b参数设置默认值为None, 如果用户传了b参数,b必须是int类型,于是可以设置b: int = None

def fuc1(a: int, b: int = None) -> int:
    if b:
        print('a+b的值为:', a+b)
        return a + b
    else:
        print('a的值为:', a)
        return a


if __name__ == '__main__':
    fuc1(2)

以上代码在pycharm 编辑器上执行是没有问题的,但是有些编辑器并不能识别b: int = None 这种语法。于是就有了 Optional 类。

Optional 可选类型

Optional 的作用是可选类型,作用几乎和带默认值的参数等价。不同的是使用Optional会告诉你的IDE或者框架:这个参数除了给定的默认值外还可以是None,而且使用有些静态检查工具如mypy时,对 a: int =None这样类似的声明可能会提示报错,但使用a :Optional[int] = None不会。

typing.Optional 可选类型
Optional[X] 等价于 Union[X, None]
请注意,这与可选参数的概念不同,后者是默认参数,具有默认值的可选参数Optional 仅在其类型注释中不需要限定符,因为它是可选的。
例如:

def foo(arg: int = 0) -> None:
   ...

另一方面,如果 None 允许使用显示值,则Optional 无论参数是否可选,的适合使用,例如

def foo(arg: Optional[int] = None) -> None:
   ...

Optional[X] 等价于 Union[X, None],当Optional参数的默认值为None时

from typing import Optional


def func(a: int, b: Optional[int] = None) -> None:
    """Optional[int]=None"""
    if b:
        print("a+b的值:", a+b)
    else:
        print("b is None")


if __name__ == '__main__':
    func(2)

运行结果:b is None

当Optional参数的默认值不为None,为1的时候

from typing import Optional


def func(a: int, b: Optional[int] = 1) -> None:
    """Optional[int]=None"""
    if b:
        print("a+b的值:", a+b)
    else:
        print("b is None")


if __name__ == '__main__':
    func(a=1, b=None)

此时传b=None,编辑器也不会提示有问题,这说明函数中b是一个可选参数,并且提示你它的默认值可以为None。

Union[X, None]

如果一个参数可以是2种类型,上面的函数b参数,可以是None, 也可以是int, 于是可以这样写

from typing import Optional, Union


def func(a: int, b: Union[None, int] = 1) -> None:
    """Optional[int]=None"""
    if b:
        print("a+b的值:", a+b)
    else:
        print("b is None")


if __name__ == '__main__':
    func(a=1, b=None)

再举个例子,函数的参数a可以是str 和 int 两种类型,返回值也可以是 str 和 int

from typing import Union


def fun1(a: Union[str, int]) -> Union[str, int]:
    """str or int"""
    return a

于是可以看到在编辑器中函数的传str 和 int不会提示语法问题,传其它的None 或 list就会有语法提示。

pydantic 中的字段类型

pydantic 使用标准库类型,支持来自 python 标准库的许多常见类型。

None,type(None)或Literal[None] 只允许None值
bool 布尔值
int pydantic用于int(v)将类型强制转换为int;
float 同样,float(v)用于将值强制为浮点数
str 字符串按原样接受,int float使用Decimal强制转换,使用转换str(v),bytes继承自的枚举使用转换,所有其他类型都会导致错误bytearray v.decode() str v.value
bytes bytes按原样接受,bytearray使用转换,使用 , 和 , 进行转换,bytes(v)使用强制转换str v.encode() int float Decimal str(v).encode()
list 允许list, tuple, set, frozenset, deque, 或生成器并强制转换为列表
tuple 允许list, tuple, set, frozenset, deque, 或生成器并强制转换为元组
dict dict(v)用于尝试转换字典
set 允许list, tuple, set, frozenset, deque, 或生成器并强制转换为集合
deque 允许list, tuple, set, frozenset, deque, 或生成器并强制转换为双端队列
typing.Any 允许任何值,包括None,因此Any字段是可选的
typing.Annotated 根据PEP-593允许使用任意元数据包装另一种类型。提示可能包含对function的 Annotated单个调用,但其他元数据将被忽略并使用根类型
typing.TypeVar 限制基于constraintsor允许的值bound
typing.Union 参考前面的
typing.Optional Optional[x]简写Union[x, None]
… 还有很多

以上是关于pydantic学习与使用-3.Typing 类型中的 Optional 和 Union的主要内容,如果未能解决你的问题,请参考以下文章

pydantic学习与使用-9.枚举类型(enum)

pydantic学习与使用-10.日期时间类型(datetime)

pydantic学习与使用-2.基本模型(BaseModel)使用

pydantic学习与使用-11.pycharm插件pydantic 语法提示功能

FastApi学习 Pydantic 做类型强制检查

FastAPI Web框架 [Pydantic]