跳到内容

高级 Python 类型

以下是一些在使用 Python 类型时可能会用到的额外思路。

使用 UnionOptional

如果由于某种原因你的代码无法使用 |(例如它不在类型注解中,而是在类似 response_model= 的地方),你可以使用 typing 模块中的 Union 来代替竖线(|)。

例如,你可以声明某项内容可以是 strNone

from typing import Union


def say_hi(name: Union[str, None]):
        print(f"Hi {name}!")

typing 还有一个快捷方式,即使用 Optional 来声明某项内容可以是 None

这是我个人非常主观的一点建议

  • 🚨 避免使用 Optional[SomeType]
  • 请改为 ✨ 使用 Union[SomeType, None] ✨。

两者是等价的,底层实现也完全相同,但我建议使用 Union 而不是 Optional。因为“optional”(可选)这个词似乎暗示该值是可选的,但它实际上代表的是“它可以是 None”,即使它并非可选参数且仍然是必需的。

我认为 Union[SomeType, None] 能更明确地表达其含义。

这仅仅是关于词汇和名称的问题,但这些词汇会影响你和你的团队对代码的思考方式。

举个例子,来看这个函数

from typing import Optional


def say_hi(name: Optional[str]):
    print(f"Hey {name}!")

参数 name 被定义为 Optional[str],但它并非可选,你不能在不传递该参数的情况下调用此函数

say_hi()  # Oh, no, this throws an error! 😱

name 参数依然是必需的(而非可选的),因为它没有默认值。不过,name 确实接受 None 作为值

say_hi(name=None)  # This works, None is valid 🎉

好消息是,在大多数情况下,你都可以直接使用 | 来定义类型的联合

def say_hi(name: str | None):
    print(f"Hey {name}!")

所以,通常情况下你不需要纠结于 OptionalUnion 这类名称。😎