类型声明
什么是类型推断
Python 运行时并不强制标注函数和变量类型。 类型标注可被用于第三方工具,比如类型检查器、集成开发环境、静态检查器等。
说白了就是虽然python 不支持定义类型这样的强类型操作,但是可以通过声明一个类型来达到类似的效果,不过不是强制性的
typing
python 3.5推出的一个类型定义模块,里面内置了很多常用类型,
from typing import
Any,
Callable, # 可调用的 同步函数
Coroutine, # 异步函数
Tuple,
List,
Union # 与3.9的 | 等价,表示多种类型 Union[str,int]
pydantic
是一个用来用来执行数据校验的 Python 库。
from pydantic import
BaseModel, # 可以用类的方式定义复杂类型
dataclass,
内置类型
None
,type(None)
或Literal[None]
只允许None
值- bool 布尔类型
- int 整数类型
- float 浮点数类型
- str 字符串类型
- bytes 字节类型
- list 允许
list
,tuple
,set
,frozenset
,deque
, 或生成器并转换为列表 - tuple 允许
list
,tuple
,set
,frozenset
,deque
, 或生成器并转换为元组 - dict 字典类型
- set 允许
list
,tuple
,set
,frozenset
,deque
, 或生成器和转换为集合; - frozenset 允许
list
,tuple
,set
,frozenset
,deque
, 或生成器和强制转换为冻结集 - deque 允许
list
,tuple
,set
,frozenset
,deque
, 或生成器和强制转换为双端队列 - datetime 的
date
,datetime
,time
,timedelta
等日期类型 - typing 中的
Deque, Dict, FrozenSet, List, Optional, Sequence, Set, Tuple, Union,Callable,Pattern
等类型 - FilePath,文件路径
- DirectoryPath 目录路径
- EmailStr 电子邮件地址
- NameEmail 有效的电子邮件地址或格式
- PyObject 需要一个字符串并加载可在该虚线路径中导入的 python 对象;
- Color 颜色类型
- AnyUrl 任意网址
- SecretStr、SecretBytes 敏感信息,将被格式化为
'**********'
或''
- Json 类型
- PaymentCardNumber 支付卡类型
- 约束类型,可以使用
con*
类型函数限制许多常见类型的值 - conlist
严格类型
防止强制兼容类型
StrictStr
StrictBytes
StrictInt
StrictFloat
StrictBool
item_type: Type[T]: 列表项的类型
min_items: int = None: 列表中的最小项目数
max_items: int = None: 列表中的最大项目数
strict: bool = False: 控制类型强制
gt: int = None: 强制整数大于设定值
ge: int = None: 强制整数大于或等于设定值
lt: int = None: 强制整数小于设定值
le: int = None: 强制整数小于或等于设定值
multiple_of: int = None: 强制整数为设定值的倍数
strict: bool = False: 控制类型强制
gt: float = None: 强制浮点数大于设定值
ge: float = None: 强制 float 大于或等于设定值
lt: float = None: 强制浮点数小于设定值
le: float = None: 强制 float 小于或等于设定值
multiple_of: float = None: 强制 float 为设定值的倍数
gt: Decimal = None: 强制十进制大于设定值
ge: Decimal = None: 强制十进制大于或等于设定值
lt: Decimal = None: 强制十进制小于设定值
le: Decimal = None: 强制十进制小于或等于设定值
max_digits: int = None: 小数点内的最大位数。它不包括小数点前的零或尾随的十进制零
decimal_places: int = None: 允许的最大小数位数。它不包括尾随十进制零
multiple_of: Decimal = None: 强制十进制为设定值的倍数
strip_whitespace: bool = False: 删除前尾空格
to_lower: bool = False: 将所有字符转为小写
strict: bool = False: 控制类型强制
min_length: int = None: 字符串的最小长度
max_length: int = None: 字符串的最大长度
curtail_length: int = None: 当字符串长度超过设定值时,将字符串长度缩小到设定值
regex: str = None: 正则表达式来验证字符串
strip_whitespace: bool = False: 删除前尾空格
to_lower: bool = False: 将所有字符转为小写
min_length: int = None: 字节串的最小长度
max_length: int = None: 字节串的最大长度
无返回值的函数
# 普通无返回值,无参数的 【同步】函数
NoArgsNoReturnFuncT = Callable[[], None]
# 普通无返回值,无参数的 【异步】函数
NoArgsNoReturnAsyncFuncT = Callable[[], Coroutine[Any, Any, None]]
# 装饰器
NoArgsNoReturnDecorator = Callable[
[NoArgsNoReturnFuncT | NoArgsNoReturnAsyncFuncT], NoArgsNoReturnAsyncFuncT
]
枚举类型
from enum import Enum
class Color(Enum):
RED = 'red'
GREEN = 'green'
BLUE = 'blue'
# 使用枚举
print(Color.RED.value) # 输出: red
print(Color.GREEN.value) # 输出: green
print(Color.BLUE.value) # 输出: blue
# 遍历枚举成员
for color in Color:
print(color.name, color.value)
字符串枚举
通过从 str
继承,可以明确声明当前的枚举类型必须是string
class ModelNae(str, Enum):
alexnet = "alexnet"
resnet = "resnet"
lenet = "lenet"
创建类型
TinyInt = NewType("tinyInt(0, 255)", tinyInt())
SmallInt = NewType("smallInt(-32767, 32767)", smallInt())
联合类型(Union)
在Python的typing
模块中,Union
是一个很有用的工具,它允许你指定一个变量可以是多个类型中的一个。这对于那些可能接收不同类型参数的函数或方法特别有用。
Union
的基本使用方式是通过逗号分隔可能的类型,然后将其放在Union
内部。但是,从Python 3.9开始,你可以直接使用类型注解的联合(不需要显式地写Union
),只需要用逗号分隔即可。不过,为了兼容性和明确性,很多开发者还是选择显式地使用Union
。
下面是Union
的详细使用方式:
显式使用Union
在Python 3.9之前,你需要显式地从typing
模块导入Union
,并用它来指定可能的类型:
from typing import Union
def example_function(arg: Union[int, str, float]) -> None:
if isinstance(arg, int):
print("Received an integer:", arg)
elif isinstance(arg, str):
print("Received a string:", arg)
elif isinstance(arg, float):
print("Received a float:", arg)
example_function(123) # 输出: Received an integer: 123
example_function("hello") # 输出: Received a string: hello
example_function(3.14) # 输出: Received a float: 3.14
隐式使用Union(Python 3.9+)
从Python 3.9开始,你可以直接使用逗号分隔的类型注解来表示联合类型,而不需要显式地导入和使用Union
:
def example_function(arg: int | str | float) -> None:
if isinstance(arg, int):
print("Received an integer:", arg)
elif isinstance(arg, str):
print("Received a string:", arg)
elif isinstance(arg, float):
print("Received a float:", arg)
# 调用方式与之前相同
使用Union时的注意事项
- 当使用
Union
时,类型检查器会期望你提供的参数是列出的类型之一。 - 在使用
isinstance
或类似函数时,你仍然需要手动检查参数的类型,因为Python在运行时不会强制类型。 Union
也可以与其他类型构造(如List
、Dict
等)结合使用,以指定更复杂的类型组合。
其他类型构造与Union结合使用
例如,如果你想指定一个列表,其元素可以是整数或字符串,你可以这样做:
from typing import Union, List
def process_list(lst: List[Union[int, str]]) -> None:
for item in lst:
if isinstance(item, int):
print("Integer:", item)
elif isinstance(item, str):
print("String:", item)
process_list([1, 2, "three", "four"])
在这个例子中,lst
参数被指定为一个列表,其元素可以是整数或字符串。