最近在学习fastAPI,在学习查询参数(请求参数)的时候对这个很疑惑,学习一下
1. Union
Union
出自 Python 的 typing
模块,用来表示 一个变量 / 参数 / 返回值可能有多种类型 。
语法:
python
from typing import Union
def func(x: Union[int, str]) -> Union[str, list]:
if isinstance(x, int):
return str(x) # 返回 str
else:
return [x] # 返回 list
这里 Union[int, str]
就表示 x
既可以是 int
也可以是 str
。
-
静态类型检查器(如 mypy、pyright)会在分析时帮你检查。
-
运行时
Union
并不会强制限制,它只是个 类型提示。
Python 3.10 以后,Union
可以用 管道符号 |
简写:
python
def func(x: int | str) -> str | list:
...
2. Optional
Optional
本质就是 Union[SomeType, None]
的语法糖。
语法:
python
from typing import Optional
def get_name(flag: bool) -> Optional[str]:
if flag:
return "Alice"
else:
return None
等价于:
python
def get_name(flag: bool) -> Union[str, None]:
...
所以:
-
Optional[T]
=Union[T, None]
。 -
你只在需要允许
None
的地方用它,语义更清晰。
3. 区别总结
-
Union :多种可能类型(至少 2 种及以上)。
例:
Union[int, str, list]
-
Optional :某个类型 +
None
的简写。例:
Optional[str]
=Union[str, None]
所以说,Optional
是 Union
的 特例。
4. 实战中的最佳实践
-
当参数或返回值里可能出现多种不同类型 → 用
Union
。pythondef load_config(path: str) -> Union[dict, list]: ...
-
当参数或返回值要么是某类型,要么就是
None
→ 用Optional
。pythondef find_user(id: int) -> Optional[str]: ...
5. 一个常见坑
很多人会写:
python
def foo(x: Optional[str] = ""):
...
其实这个没意义,因为默认值是 ""
,永远不会是 None
。
如果你真要允许 None
,应该写:
python
def foo(x: Optional[str] = None):
...
Union、Optional 的价值主要在 可读性 和 静态类型检查。