python类型注解

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模块

内置提供的类型:intstrfloat,typing模块提供的类型:DictListTuble...

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

原文地址:https://www.cnblogs.com/KbMan/p/12095857.html

时间: 2024-10-09 09:33:30

python类型注解的相关文章

python 类型注解

函数定义的弊端 python 是动态语言,变量随时可以被赋值,且能赋值为不同类型 python 不是静态编译型语言,变量类型是在运行器决定的 动态语言很灵活,但是这种特性也是弊端 def add(x,y): return x+y print(add(4,5)) print(add('hello','world')) print(add(4,'hello')) #报错,TypeError: unsupported operand type(s) for +: 'int' and 'str' 难发现

Python类型注解(inspect模块)

函数定义的弊端 Python是动态语言,变量随时可以被赋值,且能赋值为不同的类型,同时Python不是静态编译型语言,变量类型是在运行器决定的,动态语言很灵活,但是这种特性也是弊端. def add(x, y): return x + y print(add(4, 5)) print(add('hello', 'world')) add(4, 'hello') # 结果为: 9 helloworld ------------------------------------------------

?Python 3 新特性:类型注解——类似注释吧,反正解释器又不做校验

?Python 3 新特性:类型注解 Crossin ? 上海交通大学 计算机应用技术硕士 95 人赞同了该文章 前几天有同学问到,这个写法是什么意思: def add(x:int, y:int) -> int: return x + y 我们知道 Python 是一种动态语言,变量以及函数的参数是不区分类型.因此我们定义函数只需要这样写就可以了: def add(x, y): return x + y 这样的好处是有极大的灵活性,但坏处就是对于别人代码,无法一眼判断出参数的类型,IDE 也无法

Python3新特性 类型注解 以及 点点点

Python3新特性 类型注解 以及 点点点 ... Python3 的新特性 Python 是一种动态语言,变量以及函数的参数是 不区分类型 的 在 函数中使用类型注解 相当于 给 形参的 类型 设置了一个备注 # 使用类型注解 a b 参数需要 int 类型的 变量 def func(a: int = ..., b: int = ...): return a + b 使用 PyCharm 编写python代码时 函数调用会有默认参数的 提示 如果传递的 参数不是 指定的类型 正常使用也不会报

介绍几款 Python 类型检查工具

微软在 Github 上开源了一个 Python 静态类型检查工具:pyright ,引起了社区内的多方关注. 微软在开源项目上的参与力度是越来越大了,不说收购 Github 这种大的战略野心,只说它家开源的 VS Code 编辑器,在猿界已经割粉无数,连我们 Python 圈的红人 Kenneth Reitz (多个开源项目的作者,包括 requests.requests-html.responder等)都对它赞不绝口. 如今开源的 Pyright ,口碑还不错,那我们就来看看它有啥本事,顺便

typing-python用于类型注解的库

简介 动态语言的灵活性使其在做一些工具,脚本时非常方便,但是同时也给大型项目的开发带来了一些麻烦. 自python3.5开始,PEP484为python引入了类型注解(type hints),虽然在pep3107定义了函数注释(function annotation)的语法,但仍然故意留下了一些未定义的行为.现在已经拥有许多对于静态类型的分析的第三方工具,而pep484引入了一个模块来提供这些工具,同时还规定一些不能使用注释(annoation)的情况 #一个典型的函数注释例子,为参数加上了类型

C Python类型互换

从Python到C的转换用PyArg_Parse*系列函数,int PyArg_ParseTuple():把Python传过来的参数转为C:int PyArg_ParseTupleAndKeywords()与PyArg_ParseTuple()作用相同,但是同时解析关键字参数:它们的用法跟C的sscanf函数很像,都接受一个字符串流,并根据一个指定的格式字符串进行解析,把结果放入到相应的指针所指的变量中去,它们的返回值为1表示解析成功,返回值为0表示失败. 从C到Python的转换函数是PyOb

Java 8的类型注解:工具和机会

在以前的Java版本中,开发者只能将注解(Annotation)写在声明中.对于Java 8,注解可以写在使用类型的任何地方,例如声明.泛型和强制类型转换等语句: @Encrypted String data;List strings;myGraph = (@Immutable Graph) tmpGraph; 乍一看,类型注解并不是Java新版本最炫的特性.事实上,注解只是语法!工具决定了注解的的语义(即,它们的含义和行为).本文介绍新的注解语法和实用工具,以提高生产力和构建更高质量的软件.

Java 8 新特性:扩展注解(类型注解和重复注解) ——诺诺"涂鸦"记忆

----------   诺诺学习技术交流博客.期待与您交流!    ---------- 详情请查看:http://blog.csdn.net/sun_promise  注解 (注:先回顾下JDK1.5版本出现的注解 ,然后再解释JDK 8的注解 更新内容.) 一.注解(JDK1.5) 1.注解(@): 注解就相当于一种标记,在程序中加了注解就等于为程序加了某种标记.(JDK1.5新特性). 2.作用: 告诉javac编译器或者java开发工具--向其传递某种信息,作为一个标记. 3.了解注解