Skip to main content

类型声明

什么是类型推断

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,

内置类型

  • Nonetype(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, 或生成器和强制转换为双端队列
  • datetimedate,datetime,time,timedelta 等日期类型
  • typing 中的 Deque, Dict, FrozenSet, List, Optional, Sequence, Set, Tuple, Union,Callable,Pattern等类型
  • FilePath,文件路径
  • DirectoryPath 目录路径
  • EmailStr 电子邮件地址
  • NameEmail 有效的电子邮件地址或格式
  • PyObject 需要一个字符串并加载可在该虚线路径中导入的 python 对象;
  • Color 颜色类型
  • AnyUrl 任意网址
  • SecretStrSecretBytes 敏感信息,将被格式化为'**********'''
  • 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也可以与其他类型构造(如ListDict等)结合使用,以指定更复杂的类型组合。

其他类型构造与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参数被指定为一个列表,其元素可以是整数或字符串。