一篇文章带你了解python中的typing模块和类型注解

目录
  • typing模块
    • Dict
    • List
    • Tuple
    • set/AbstractSet
    • Sequence
    • NoReturn
    • Any
    • TypeVar
    • NewType
    • Callable
    • Union
    • Optional
    • Generator
  • 总结

function annotation 写法:

  • 使用冒号 : 加类型代表参数类型

    • 默认值参数示例:b: int = 2
  • 使用 -> 加类型代表返回值类型

python解释器运行时并不会检查类型,类型不对也不会抛异常,仅仅是注解而已。示例:

def plus(a: int, b: int = 2) -> int:
    return a + b

python 解析器并不会在意类型注解,严格来说这是不对的,Python 会把类型信息放在 __annotations__ 属性中:

>>> def foo(a: str):
...     print('hello', a)
...

>>> foo.__annotations__
{'a': str}

>>> class Bar:
...     a: str
...     b: int

>>> Bar.__annotations__
{'a': str, 'b': int}

typing模块

内置提供的类型:int 、str 、float,typing模块提供的类型:Dict 、List 、Tuble...

typing使用方括号 Dict[str, int] 而不是圆括号 Dict(str, int)

Dict

Dict[str, int]: 表示一个 keys 的类型为 str,values 的类型为 int 的字典,比如 {"a": 1, "b": 2}

from typing import Dict
Dict[str, Dict[str, List[str]]]如下:
{
    '原木镇': {
        '第一小学': ['张伟', '王伟', '王芳'],
        '第二小学': ['李伟', '李娜'],
    },
    '鸽子镇': {
        '高山中学': ['张敏', '李静'],
        '亿百中学': ['王静']
        '蟒蛇小学': ['刘伟', '王秀英']
    }
}

List

List[int] 表示由整型组成的列表,比如[0, 1, 1, 2, 3]

List[List[int]] = [[1, 2], [2, 3]]

Tuple

Tuple[int, float, str] is a tuple of an int, a float and a string.

person: Tuple[str, int, float] = ('Mike', 22, 1.75)

set/AbstractSet

根据官方文档,Set 推荐用于注解返回类型,AbstractSet 用于注解参数

def describe(s: AbstractSet[int]) -> Set[int]:
    return set(s)

Sequence

Sequence,是 collections.abc.Sequence 的泛型,在某些情况下,我们可能并不需要严格区分一个变量或参数到底是列表 list 类型还是元组 tuple 类型,我们可以使用一个更为泛化的类型,叫做 Sequence,其用法类似于 List

def square(elements: Sequence[float]) -> List[float]:
    return [x ** 2 for x in elements]

NoReturn

NoReturn,当一个方法没有返回结果时,为了注解它的返回类型,我们可以将其注解为NoReturn

def hello() -> NoReturn:
    print('hello')

Any

Any,可以代表所有类型,所有的无参数类型注解和返回类型注解的都会默认使用 Any 类型,以下两个函数等价:

def add(a):
    return a + 1

def add(a: Any) -> Any:
    return a + 1

TypeVar

TypeVar,自定义兼容特定类型的变量,比如有的变量声明为 int、float、None 都是符合要求的,实际就是代表任意的数字或者空内容都可以,其他的类型则不可以,比如列表 list、字典 dict 等等,像这样的情况,我们可以使用 TypeVar 来表示。

height = 1.75
Height = TypeVar('Height', int, float, None)
def get_height() -> Height:
    return height

NewType

newType,声明一些具有特殊含义的类型,像 Tuple 的例子一样,我们需要将它表示为 Person,即一个人的含义,但但从表面上声明为 Tuple 并不直观,所以我们可以使用 NewType 为其声明一个类型,如:

Person = NewType('Person', Tuple[str, int, float])
person = Person(('Mike', 22, 1.75))

实际上 person 就是一个 tuple 类型,我们可以对其像 tuple 一样正常操作。

Callable

Callable,可调用类型,通常用来注解一个方法, 在声明的时候需要使用 Callable[[Arg1Type, Arg2Type, ...], ReturnType] 这样的类型注解,将参数类型和返回值类型都要注解出来,例如:

def date(year: int, month: int, day: int) -> str:
    return f'{year}-{month}-{day}'

def get_date_fn() -> Callable[[int, int, int], str]:
    return date

-> Callable[[int, int, int], str]: 中括号内分别标记了返回的方法的参数类型和返回值类型。

Union

Union,联合类型,Union[X, Y] 代表要么是 X 类型,要么是 Y 类型。

Union[Union[int, str], float] == Union[int, str, float]
Union[int] == int
Union[int, str, int] == Union[int, str]
# 无参数顺序
Union[int, str] == Union[str, int]

在一些方法参数声明的时候比较有用,比如一个方法,要么传一个字符串表示的方法名,要么直接把方法传过来:

def process(fn: Union[str, Callable]):
    if isinstance(fn, str):
        # str2fn and process
        pass
    elif isinstance(fn, Callable):
        fn()

这样的声明在一些类库方法定义的时候十分常见。

Optional

Optional,意思是说这个参数可以为空或已经声明的类型,即 Optional[X] 等价于 Union[X, None]

Optional 并不等价于可选参数,当它作为参数类型注解的时候,不代表这个参数可以不传递,而是说这个参数可以传None,不传也会报错。

当一个方法执行结果,如果执行完毕就不返回错误信息, 如果发生问题就返回错误信息,则可以这么声明:

def judge(result: bool) -> Optional[str]:
    if result: return 'Error Occurred'

Generator

Generator,想代表一个生成器类型,可以使用 Generator,它的声明比较特殊,其后的中括号紧跟着三个参数,分别代表 YieldType、SendType、ReturnType,如:

def echo_round() -> Generator[int, float, str]:
    sent = yield 0
    while sent >= 0:
        sent = yield round(sent)
    return 'Done'

在这里 yield 关键字后面紧跟的变量的类型就是 YieldType,yield 返回的结果的类型就是 SendType,最后生成器 return 的内容就是 ReturnType。

当然很多情况下,生成器往往只需要 yield 内容就够了,我们是不需要 SendType 和 ReturnType 的,可以将其设置为空,如:

def infinite_stream(start: int) -> Generator[int, None, None]:
    while True:
        yield start
        start += 1

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Python中typing模块与类型注解的使用方法

    实例引入 我们知道 Python 是一种动态语言,在声明一个变量时我们不需要显式地声明它的类型,例如下面的例子: a = 2 print('1 + a =', 1 + a) 运行结果: 1 + a = 3 这里我们首先声明了一个变量 a,并将其赋值为了 2,然后将最后的结果打印出来,程序输出来了正确的结果.但在这个过程中,我们没有声明它到底是什么类型. 但如果这时候我们将 a 变成一个字符串类型,结果会是怎样的呢?改写如下: a = '2' print('1 + a =', 1 + a) 运行结

  • python 编码中为什么要写类型注解?

    1.背景 我们先谈谈为什么在Python编码过程中强烈推荐使用类型注解 ? Python对于初学者来说是非常好上手,原因是在于对计算机底层原理的高度封装和动态语言的特性使得Python用起来非常的舒适.但这种"舒适"是有代价的,我们可能听说过一句形容动态语言的话,动态一时爽,一直动态一直爽.为什么会这么说?动态的确会赋予我们在编码时更多的灵活性与能力,但是动态带来的是更多的不确定性及混乱,导致了后来的维护者甚至作者自己都会产生很大的维护压力(可以想象一个经过几年迭代的复杂系统,如果大部

  • Python函数参数和注解的使用

    四种参数 Python函数func定义如下: def func(first, *args, second="Hello World", **kwargs): print(first) print(args) print(second) print(kwargs) func("dongfanger", "san", py="good") 运行后会输出: dongfanger ('san',) Hello World {'py':

  • 深入浅析Python 函数注解与匿名函数

    函数注解与匿名函数 关于函数参数的定义,调用以及函数参数的内容,在下面的文章中已经做了初步的介绍,有需要的可以访问进行了解: Python 函数 函数注解 在编写函数,当下肯定清楚函数如何使用的.若是函数较为复杂,过段时间,编写者有可能需要花一段时间去重新了解函数的使用,那其他使用者也同样会遇到这样的困惑. 所以当编写完函数后,可以为函数的参数添加一些额外的信息.这里给函数参数添加注解,能够提示程序员如何正确使用这个函数.如下示例: def add(x:int, y:int) -> int: '

  • Python 注解方式实现缓存数据详解

    目录 背景 拿来即用 实践过程 通过装饰器类简化代码 总结 背景 每次加载数据都要重新Load,想通过加入的注解方式开发缓存机制,每次缓存不用写代码了 缺点:目前仅支持一个返回值,虽然能弄成字典,但是已经满足个人需求,没动力改(狗头). 拿来即用 新建文件 Cache.py class Cache: def __init__(self, cache_path='.', nocache=False): self.cache_path = cache_path self.cache = not no

  • 一篇文章带你了解python中的typing模块和类型注解

    目录 typing模块 Dict List Tuple set/AbstractSet Sequence NoReturn Any TypeVar NewType Callable Union Optional Generator 总结 function annotation 写法: 使用冒号 : 加类型代表参数类型 默认值参数示例:b: int = 2 使用 -> 加类型代表返回值类型 python解释器运行时并不会检查类型,类型不对也不会抛异常,仅仅是注解而已.示例: def plus(a:

  • 一篇文章带你了解Python中的装饰器

    目录 前言 Python 中的装饰器是什么 语法糖 使用 Python 装饰器修改函数行为 使用 Python 装饰器对函数进行计时 使用 Python 装饰器将有用信息记录到终端 Web app 中使用的装饰器 将参数传递给 Python 装饰器 使用多个 Python 装饰器 总结 前言 本文将带你学习装饰器在 Python 中的工作原理,如果在函数和类中使用装饰器,如何利用装饰器避免代码重复(DRY 原则,Don’t Repeat Yourself ). Python 中的装饰器是什么 装

  • 一篇文章带你了解python标准库--time模块

    目录 1. 调用语法: 2. time概述 3. 时间获取 4. 时间格式化(将时间以合理的方式展示出来) 5. 程序计时应用 6. 示例 总结 Time库是python中处理时间的标准库 1. 调用语法: import time time.<b>() 计算机时间的表达,提供获取系统时间并格式化输出功能 提供提供系统精确即使功能,用于程序性能分析 2. time概述 time库包括三类函数 时间获取: time() ctime() gmtime() 时间格式化: strftime() strp

  • 一篇文章带你了解Python中的类

    目录 1.类的定义 2.创建对象 3.继承 总结 1.类的定义 创建一个rectangle.py文件,并在该文件中定义一个Rectangle类.在该类中,__init__表示构造方法.其中,self参数是每一个类定义方法中的第一个参数(这里也可以是其它变量名,但是Python常用self这个变量名).当创建一个对象的时候,每一个方法中的self参数都指向并引用这个对象,相当于一个指针.在该类中,构造方法表示该类有_width和_height两个属性(也称作实例变量),并对它们赋初值1. __st

  • 一篇文章带你了解python标准库--math模块

    目录 1. math模块中的常用函数 2. 案例 2.1 浮点数求整 2.2 对元组里的每个元素求和 2.3 求数的绝对值 总结 python语言的一大优势:为科学计算提供了大量的支持功能,math模块提供了很多数学计算函数. math模块定义了一些数学模块,这个模块属于编译系统自带,因此它可以被无条件调用,需要注意的是,这些函数无法应用于复数. 1. math模块中的常用函数 2. 案例 2.1 浮点数求整 1.用trunc(x)取整,x为浮点数 >>> import math >

  • 一篇文章带你了解python标准库--random模块

    目录 1. random库基本介绍 2. random库概述 2.1 基本随机函数 2.2 扩展随机函数 3. 随机数函数的使用 4. 实例 总结 1. random库基本介绍 Random库时使用随机数的python标准库 伪随机数:采用梅森旋转算法生成的(伪)随机序列中的元素 Random库主要用于生成随机数 使用random库:import random 2. random库概述 Random库包含两类函数,常用共8个 基本随机函数:seed() random() 扩展随机函数:randi

  • 一篇文章带你了解python标准库--os模块

    目录 1. os库基本介绍 2. os库之路径操作 3. os库之进程管理 4. os库之环境参数 5. 案例 总结 目前,计算机上主流的操作系统有Windows.Unix.Mac OS等,os模块为多操作系统的访问提供了相关功能的支持,涉及对文件相关操作功能的实现,系统访问path路径的操作,shell命令行操作,Linux扩展属性的操作,流程管理,CPU等硬件相关信息的获取,基于操作系统的真正的随机数的操作及相关的一些系统常量进行介绍. 1. os库基本介绍 Os库提供通用的.基本的操作系统

  • 一篇文章带你了解python标准库--sys模块

    目录 sys部分常用函数 1.sys.path函数用于获取模块文件搜索路径的字符串列表,或临时指定新的搜索路径 2.sys.platform为操作系统标识符判断函数 3.getwindowsversion()函数返回描述当前正在运行Windows版本信息的元组 总结 sys模块提供了与python解释器紧密相关的一些变量和函数. sys部分常用函数 函数 说明 path 获取模块文件搜索路径的字符串,或临时指定新搜索路径 platform 操作系统标识符判断函数 getwindowsversio

  • 一篇文章带你了解python标准库--datetime模块

    目录 1. datetime模块介绍 1.1 datetime模块包含的类 1.2 datetime模块中包含的常量 2. datetime实例的方法 3. 日期格式化符号 总结 1. datetime模块介绍 1.1 datetime模块包含的类 1.2 datetime模块中包含的常量 2. datetime实例的方法 案例代码 import locale from datetime import datetime,date,time locale.setlocale(locale.LC_C

  • 一篇文章带你吃透JavaScript中的DOM知识及用法

    目录 一.前言 二.DOM框架 三.认识DOM节点 四.JS访问DOM 1.获取节点 2.改变 HTML 3.改变 CSS 4.检测节点类型 5.操作节点间的父子及兄弟关系 6.操作节点属性 7.创建和操作节点 总结 一.前言 DOM:Document Object Model(文档对象模型),定义了用户操作文档对象的接口,可以说DOM是自HTML将网上相关文档连接起来后最伟大的创新.它使得用户对HTML有了空前的访问能力,并使开发者将HTML作为XML文档来处理. 本文知识导图如下: 二.DO

随机推荐