python之typing

typing介绍

Python是一门动态语言,很多时候我们可能不清楚函数参数类型或者返回值类型,很有可能导致一些类型没有指定方法,在写完代码一段时间后回过头看代码,很可能忘记了自己写的函数需要传什么参数,返回什么类型的结果,就不得不去阅读代码的具体内容,降低了阅读的速度,typing模块可以很好的解决这个问题。

Python的typing包是从Python 3.5版本引入的标准库,它提供了类型提示和类型注解的功能,用于对代码进行静态类型检查和类型推断。typing模块中定义了多种类型和泛型,以帮助开发者代码的可读性、可维护性和可靠性。

typing的作用

typing包的主要功能如下:

  1. 类型注解:typing包提供了多种用于类型注解的工具,包括基本类型(如int、str)、容器类型(如List、Dict)、函数类型(如Callable、Tuple)、泛型(如Generic、TypeVar)等。通过类型注解,可以在函数声明、变量声明和类声明中指定参数的类型、返回值的类型等,以增加代码的可读性和可靠性。
  2. 类型检查:通过与第三方工具(如mypy)集成,可以对使用了类型注解的代码进行静态类型检查。类型检查可以帮助发现潜在的类型错误和逻辑错误,以提前捕获问题并改善代码的质量。
  3. 泛型支持:typing模块提供了对泛型的支持,使得可以编写更通用和灵活的代码。通过泛型,可以在函数和类中引入类型参数,以处理各种类型的数据。
  4. 类、函数和变量装饰器:typing模块提供了一些装饰器,如@overload、@abstractmethod、@final等,用于修饰类、函数和变量,以增加代码的可读性和可靠性。

除了typing包,还有typing_extensions模块,它是typing模块的扩展,提供了一些额外的功能和类型。typing_extensions中包括了一些高级的类型工具和类型别名,用于更复杂的类型定义和注解。

总的来说,typing包和typing_extensions模块为Python开发者提供了一套强大的类型提示工具,使得可以在代码中加入类型注解,并通过类型检查工具提供静态类型检查的功能,以提高代码的可读性和质量。

即, typing是python 3.5及以后版本的标准库,typing_extensions是typing模块的扩展包。

typing常用类型

以下是typing包中常用的类型和泛型。

注意,int, float,bool,str, bytes不需要import typing,Any,Union,Tuple等需要import typing

基本类型:

  • int: 整数类型
  • float: 浮点数类型
  • bool: 布尔类型
  • str: 字符串类型
  • bytes: 字节类型
  • Any: 任意类型
  • Union: 多个类型的联合类型,表示可以是其中任意一个类型
  • Tuple: 固定长度的元组类型
  • List: 列表类型
  • Dict: 字典类型,用于键值对的映射

泛型:

  • Generic: 泛型基类,用于创建泛型类或泛型函数
  • TypeVar: 类型变量,用于创建表示不确定类型的占位符
  • Callable: 可调用对象类型,用于表示函数类型
  • Optional: 可选类型,表示一个值可以为指定类型或None
  • Iterable: 可迭代对象类型
  • Mapping: 映射类型,用于表示键值对的映射
  • Sequence: 序列类型,用于表示有序集合类型
  • Type:泛型类,用于表示类型本身

typing使用示例

示例1

fun1里,标明了形参和返回值的类型,fun2中却没有。

from typing import List, Tuple, Dict

def fun1(a0: int, s0: str, f0: float, b0: bool) -> Tuple[List, Tuple, Dict, bool]:
    list1 = list(range(a0))
    tup1 = (a0, s0, f0, b0)
    dict1 = {s0: f0}
    b1 = b0
    return list1, tup1, dict1, b1

def fun2(a0, s0, f0, b0):
    list1 = list(range(a0))
    tup1 = (a0, s0, f0, b0)
    dict1 = {s0: f0}
    b1 = b0
    return list1, tup1, dict1, b1

print(fun1(5, "KeyName", 2.3, False))


print(help(fun1))
"""
Help on function fun1 in module __main__:
fun1(a0: int, s0: str, f0: float, b0: bool) -> Tuple[List, Tuple, Dict, bool]
"""

print(help(fun2))
"""
Help on function fun2 in module __main__:
fun2(a0, s0, f0, b0)
"""

由于fun1里有了完整的变量类型的注释,通过help查看其使用文档就很清楚知道怎么用该函数。

示例2

from typing import List
 
def func(a: int,b: str) -> List[int or str]:# 使用or关键字表示多种类型
    list1 = []
    list1.append(a)
    list1.append(b)
    return list1

l = func(3, "aa")
print(l) # [3, 'aa']

示例3

定义一个不确定类型的占位符T,用作函数foo的形参, 但函数返回值一定是str,通过内部做str(name)转化来保证。

import typing

T=typing.TypeVar('T',int,float,str)

def foo(name:T)->str:
    return str(name)

print(foo(2.012)) # 2.012
print(foo(35)) # 35
print(foo("hahaha")) # hahaha

示例4

typing中的Type是一个泛型类,用于表示类型本身,即你是啥类型就是啥类型,有点绕,看例子吧:

from typing import Type

value: Type[int]  # value是一个Type对象,表示int类型
value: int

即value:Type[int]和value:int是等价的。

那为什么还要有这个Type类呢,我理解它为一个更为宽松的类型标注,比如下面函数:

def ir_module(mod: Type) -> IRModule:
    """The parsing method for ir module, by using `@ir_module` as decorator.

    Parameters
    ----------
    mod : Type
        The class to be parsed as ir module.

    Returns
    -------
    ir_module : IRModule
        The parsed ir module.
    """
    if not inspect.isclass(mod):
        raise TypeError(f"Expect a class, but got: {mod}")

    m = parse(mod, utils.inspect_class_capture(mod))
    setattr(m, "__name__", mod.__name__)
    return m

这个ir_module()作为一个装饰器,mod传进来是啥就是啥,但必须要是一个类型。然后在函数里,通过inspect强制检查mod必须为一个类,不然就报错。我们在使用ir_module装饰器时,一般是这样的:

import tvm
from tvm.ir.module import IRModule
from tvm.script import tir as T

@tvm.script.ir_module
class MyModule:
    pass

ir_mod = MyModule
print("done")

即给ir_module传进去的是MyModule这个类。

Type也可用于标注函数返回值类型,比如

from typing import Type, List

def get_list_type() -> Type[List[int]]:
    return list

returned_type = get_list_type()  # returned_type是一个Type对象,表示List[int]类型

在上述示例中,Type[List[int]]表示List[int]类型本身,可以用于注解函数get_list_type的返回类型,说明该函数返回的是List[int]类型的值。通过调用get_list_type()函数得到的返回值returned_type是一个Type对象,表示List[int]类型。

或标注函数参数类型:

from typing import Type

def process_type(t: Type[str]) -> None:
    print(t)

process_type(str)  # 输出: <class 'str'>

在上述示例中,Type[str]用于注解函数process_type的参数类型,说明函数接受一个类型为str的参数。通过在调用process_type函数时传入str作为参数,可以在函数内部获取到该类型的Type对象。

 

 

posted @ 2023-12-15 15:35  X-Wolf  阅读(55)  评论(0编辑  收藏  举报