Python - typing 模块 类型提示

前言

typing 是在 python 3.5 才有的模块

类型提示

python是一种动态语言,即在运行时不用指定数据类型。

  1. 没使用类型提示时

需要使用注释才可以知道类型

# 'l1' is a list of integers
l1 = []  # type: List[int]

# 'str1' is a string (Note: initial value is a problem)
str1 = ...  # type: str

class Starship:
    # 'stats' is a class variable
    stats = {}  # type: Dict[str, int]
  1. 当使用了类型提示

from typing import List, ClassVar, Dict

# int 变量,默认值为 0
num: int = 0

# bool 变量,默认值为 True
bool_var: bool = True

# 字典变量,默认为空
dict_var: Dict = {}

# 列表变量,且列表元素为 int
primes: List[int] = []


class Starship:
    # 类变量,字典类型,键-字符串,值-整型
    stats: ClassVar[Dict[str, int]] = {}

    # 实例变量,标注了是一个整型
    num: int

此时的类型提示更像是一个约束规范,但并不是语法,也就是当你传错类型的话,它也不会报错。

  1. 变量类型提示,元组打包
# 正常的元组打包
a = 1, 2, 3

# 加上类型提示的元组打包
t: Tuple[int, ...] = (1, 2, 3)
print(t)

t = 1, 2, 3
print(t)

# py3.8+ 才有的写法
t: Tuple[int, ...] = 1, 2, 3
print(t)

t = 1, 2, 3
print(t)


# 输出结果
(1, 2, 3)
(1, 2, 3)
(1, 2, 3)
(1, 2, 3)

在这里要注意省略号的使用,不写会出现警告,但不会报错

  1. 变量类型提示-元组解包
# 正常元组解包
message = (1, 2, 3)
a, b, c = message
print(a, b, c)  # 输出 1 2 3

# 加上类型提示的元组解包
header: str
kind: int
body: Optional[List[str]]

# 不会 warning 的栗子
header, kind, body = ("str", 123, ["1", "2", "3"])

# 会提示 warning 的栗子
header, kind, body = (123, 123, ["1", "2", "3"])

!在这里提到了Optional

  1. 在类里使用类型提示
class BasicStarship:
    captain: str = 'Picard'               # 实例变量,有默认值
    damage: int                           # 实例变量,没有默认值
    stats: ClassVar[Dict[str, int]] = {}  # 类变量,有默认值

ClassVar

  • 是 typing 模块的一个特殊类

  • 它向静态类型检查器指示不应在类实例上设置此变量

3.常用类型提示

  • int,long,float: 整型,长整形,浮点型;

  • bool,str: 布尔型,字符串类型;

  • List, Tuple, Dict, Set:列表,元组,字典, 集合;

  • Iterable,Iterator:可迭代类型,迭代器类型;

  • Generator:生成器类型;

前两行小写的不需要 import,后面三行都需要通过 typing 模块 import 哦

举个简单的例子

from typing import Tuple, List, Dict


# 返回一个 Tuple 类型的数据,第一个元素是 List,第二个元素是 Tuple,第三个元素是 Dict,第四个元素可以是字符串或布尔
def add(a: int, string: str, f: float, b: bool or str) -> Tuple[List, Tuple, Dict, str or bool]:
    list1 = list(range(a))
    tup = (string, string, string)
    d = {"a": f}
    bl = b
    return list1, tup, d, bl


# 不 warn 的调用写法
print(add(1, "2", 123, True))


# 输出结果
([0], ('2', '2', '2'), {'a': 123}, True)

4.NewType

可以自定义创一个新类型

  • 主要用于类型检查

  • NewType(name, tp) 返回一个函数,这个函数返回其原本的值

  • 静态类型检查器会将新类型看作是原始类型的一个子类

  • tp 就是原始类型

5.Callable

是一个可调用对象类型,查看对象是否可调用

语法:

# 返回True或False
isinstance(对象, Callable)    

6.Any Type

  • 一种特殊的类型是 Any

  • 静态类型检查器会将每种类型都视为与 Any 兼容,将 Any 视为与每种类型兼容

# Any
from typing import Any

a = None  # type: Any
a1 = []  # OK
a2 = 2  # OK

s = ''  # type: str
s1 = a  # OK


def foo(item: Any) -> int:
    # Typechecks; 'item' 可以是任意类型
    print(item)
    return 1


foo(a)
foo(a1)
foo(a2)
foo(s)
foo(s1)

7.Union(重要)

联合类型

Union[int, str] 表示既可以是 int,也可以是 str

vars: Union[int, str]
# 等价于
vars: [int or str]


vars: Union[int]
# 等价于
vars: int

union 等价写法

Union[int] == int

最终 Union[int] 返回的也是 int 类型

Union[int, str, int] == Union[int, str]

重复的类型参数会自动忽略掉

Union[int, str] == Union[str, int]

自动忽略类型参数顺序

Union[Union[int, str], float] == Union[int, str, float]

union 嵌套 union 会自动解包

8.Optional(在leetcode看到该写法)

可选类型

和默认参数有什么不一样

  • 官方原话:可选参数具有默认值,具有默认值的可选参数不需要在其类型批注上使用 Optional,因为它是可选的

  • 不过 Optional 和默认参数其实没啥实质上的区别,只是写法不同

  • 使用 Optional 是为了让 IDE 识别到该参数有一个类型提示,可以传指定的类型和 None,且参数是可选非必传的

# 可选参数
def foo(arg: int = 0) -> None:
    ...


# 不传 arg 默认取 0
foo()

重点

  • Optional[int] 等价于 Union[int, None]

  • 意味着:既可以传指定的类型 int,也可以传 None

Optional[] 里面只能写一个数据类型

# 正确
Optional[str]
Optional[List[str]]
Optional[Dict[str, Any]]

# 错误
Optional[str, int]
Optional[Union[str, int, float]]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值