详解python3类型注释annotations实用案例


Posted in Python onJanuary 20, 2021

1、类型注解简介

Python是一种动态类型化的语言,不会强制使用类型提示,但为了更明确形参类型,自python3.5开始,PEP484为python引入了类型注解(type hints)

示例如下:

详解python3类型注释annotations实用案例 

2、常见的数据类型

  • int,long,float: 整型,长整形,浮点型
  • bool,str: 布尔型,字符串类型
  • List, Tuple, Dict, Set: 列表,元组,字典, 集合
  • Iterable,Iterator: 可迭代类型,迭代器类型
  • Generator:生成器类型
  • Sequence: 序列

3、基本的类型指定

def test(a: int, b: str) -> str:
  print(a, b)
  return 200


if __name__ == '__main__':
  test('test', 'abc')

函数test,a:int 指定了输入参数a为int类型,b:str b为str类型,-> str 返回值为srt类型。可以看到,在方法中,我们最终返回了一个int,此时pycharm就会有警告;

调用这个方法时,参数a 输入的是字符串,此时也会有警告;

but…,pycharm这玩意儿 只是提出了警告,但实际上运行是不会报错,毕竟python的本质还是动态语言

详解python3类型注释annotations实用案例

4、复杂的类型指定

指定列表

from typing import List
Vector = List[float]


def scale(scalar: float, vector: Vector) -> Vector:
  return [scalar * num for num in vector]


# type checks; a list of floats qualifies as a Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])
print(new_vector)

指定 字典、元组 类型

from typing import Dict, Tuple, Sequence

ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]


def broadcast_message(message: str, servers: Sequence[Server]) -> None:
  print(message)
  print(servers)

# The static type checker will treat the previous type signature as
# being exactly equivalent to this one.


if __name__ == '__main__':
  broadcast_message('OK', [(('127.0.0.1', 8080), {"method": "GET"})])

详解python3类型注释annotations实用案例

这里需要注意,元组这个类型是比较特殊的,因为它是不可变的。
所以,当我们指定Tuple[str, str]时,就只能传入长度为2,并且元组中的所有元素都是str类型

5、创建变量时的类型指定

对于常量或者变量添加注释

from typing import NamedTuple


class Employee(NamedTuple):
  name: str
  id: int = 3


employee = Employee('Guido')
# assert employee.id == 3  # 当类型一致时,不会输出内容,反之报错
assert employee.id == '3'  # 当类型一致时,不会输出内容,反之报错
# AssertionError

指定一个变量odd,显式的声明了它应该是整数列表。如果使用mypy来执行这个脚本,将不会收到任何提示输出,因为已经正确地传递了期望的参数去执行所有操作。

from typing import List

def odd_numbers(numbers: List) -> List:
  odd: List[int] = []
  for number in numbers:
    if number % 2:
      odd.append(number)

  return odd

if __name__ == '__main__':
  numbers = list(range(10))
  print(odd_numbers(numbers))

mypy 安装

pip install mypy

执行 mypy file,正常情况下不会报错

C:\Users\Sunny_Future\AppData\Roaming\Python\Python36\Scripts\mypy.exe tests.py

# 指定 环境变量或者 linux 下可以直接执行 mypy
# mypy tests.py

Success: no issues found in 1 source file

详解python3类型注释annotations实用案例

接下来,尝试更改一下代码,试图去添加整形之外的其他类型内容!那么执行则会检查报错

from typing import List


def odd_numbers(numbers: List) -> List:
  odd: List[int] = []
  for number in numbers:
    if number % 2:
      odd.append(number)

  odd.append('foo')

  return odd


if __name__ == '__main__':
  numbers = list(range(10))
  print(odd_numbers(numbers))

代码中添加一个行新代码,将一个字符串foo附加到整数列表中。现在,如果我们针对这个版本的代码来运行mypy

C:\Users\Sunny_Future\AppData\Roaming\Python\Python36\Scripts\mypy.exe tests.py

详解python3类型注释annotations实用案例

tests.py:114: error: Argument 1 to “append” of “list” has incompatible type “str”; expected “int”
Found 1 error in 1 file (checked 1 source file)

6、 泛型指定

from typing import Sequence, TypeVar, Union

T = TypeVar('T')   # Declare type variable


def first(l: Sequence[T]) -> T:  # Generic function
  return l[0]


T = TypeVar('T')       # Can be anything
A = TypeVar('A', str, bytes) # Must be str or bytes
A = Union[str, None]     # Must be str or None

7、再次重申

在Python 3.5中,你需要做变量声明,但是必须将声明放在注释中:

# Python 3.6
odd: List[int] = []

# Python 3.5
odd = [] # type: List[int]

如果使用Python 3.5的变量注释语法,mypy仍将正确标记该错误。你必须在 #井号之后指定type:。如果你删除它,那么它就不再是变量注释了。基本上PEP 526增加的所有内容都为了使语言更加统一。

8、不足之处

虽然指定了 List[int] 即由 int 组成的列表,但是,实际中,只要这个列表中存在 int(其他的可以为任何类型)pycharm就不会出现警告,使用 mypy 才能检测出警告!

from typing import List


def test(b: List[int]) -> str:
  print(b)
  return 'test'


if __name__ == '__main__':
  test([1, 'a'])

pycharm 并没有检测出类型错误,没有告警

详解python3类型注释annotations实用案例mypy

工具 检测到 类型异常,并进行了报错

详解python3类型注释annotations实用案例 

9、demo

# py2 引用
from__future__import annotations
class Starship:
  captain: str = 'Picard'
  damage: int
  stats: ClassVar[Dict[str, int]] = {}

  def __init__(self, damage: int, captain: str = None):
    self.damage = damage
    if captain:
      self.captain = captain # Else keep the default

  def hit(self):
    Starship.stats['hits'] = Starship.stats.get('hits', 0) + 1

enterprise_d = Starship(3000)
enterprise_d.stats = {} # Flagged as error by a type checker
Starship.stats = {} # This is OK
from typing import Dict
class Player:
  ...
players: Dict[str, Player]
__points: int

print(__annotations__)
# prints: {'players': typing.Dict[str, __main__.Player],
#     '_Player__points': <class 'int'>}
class C:
  __annotations__ = 42
  x: int = 5 # raises TypeError

到此这篇关于详解python3类型注释annotations实用案例的文章就介绍到这了,更多相关python3类型注释annotations内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
浅谈pyhton学习中出现的各种问题(新手必看)
May 17 Python
Python3爬虫爬取英雄联盟高清桌面壁纸功能示例【基于Scrapy框架】
Dec 05 Python
python数据处理 根据颜色对图片进行分类的方法
Dec 08 Python
Python面向对象之类的定义与继承用法示例
Jan 14 Python
Python设计模式之外观模式实例详解
Jan 17 Python
python交互界面的退出方法
Feb 16 Python
Dlib+OpenCV深度学习人脸识别的方法示例
May 14 Python
python识别图像并提取文字的实现方法
Jun 28 Python
Python中PyQt5/PySide2的按钮控件使用实例
Aug 17 Python
python使用yield压平嵌套字典的超简单方法
Nov 02 Python
Python利器openpyxl之操作excel表格
Apr 17 Python
python的netCDF4批量处理NC格式文件的操作方法
Mar 21 Python
python-jwt用户认证食用教学的实现方法
Jan 19 #Python
使用Python爬虫爬取小红书完完整整的全过程
Jan 19 #Python
python 自动识别并连接串口的实现
Jan 19 #Python
python爬取抖音视频的实例分析
Jan 19 #Python
python中的插入排序的简单用法
Jan 19 #Python
Python实现淘宝秒杀功能的示例代码
Jan 19 #Python
Python爬虫后获取重定向url的两种方法
Jan 19 #Python
You might like
thinkPHP下ueditor的使用方法详解
2015/12/26 PHP
php mysql操作mysql_connect连接数据库实例详解
2016/12/26 PHP
yii2多图上传组件的使用教程
2018/05/10 PHP
php实现算术验证码功能
2018/12/05 PHP
ppk谈JavaScript style属性
2008/10/10 Javascript
简单的js分页脚本
2009/05/21 Javascript
javascript实现的距离现在多长时间后的一个格式化的日期
2009/10/29 Javascript
Extjs中的GridPanel隐藏列会显示在menuDisabled中解决方法
2013/01/27 Javascript
js中 关于undefined和null的区别介绍
2013/04/16 Javascript
基于jquery实现等比缩放图片
2014/12/03 Javascript
jQuery弹出框代码封装DialogHelper
2015/01/30 Javascript
BOM系列第二篇之定时器requestAnimationFrame
2016/08/17 Javascript
原生js实现addclass,removeclass,toggleclasss实例
2016/11/24 Javascript
Javascript oop设计模式 面向对象编程简单实例介绍
2016/12/13 Javascript
老生常谈的跨域处理
2017/01/11 Javascript
jQuery插件select2利用ajax高效查询大数据列表(可搜索、可分页)
2017/05/19 jQuery
JS实现快速比较两个字符串中包含有相同数字的方法
2017/09/11 Javascript
Bootstrap treeview实现动态加载数据并添加快捷搜索功能
2018/01/07 Javascript
JavaScript使用math.js进行精确计算操作示例
2018/06/19 Javascript
JS中判断字符串存在和非空的方法
2018/09/12 Javascript
vue-router 起步步骤详解
2019/03/26 Javascript
python中使用PIL制作并验证图片验证码
2018/03/15 Python
Python中利用xpath解析HTML的方法
2018/05/14 Python
python递归函数绘制分形树的方法
2018/06/22 Python
Tornado Web Server框架编写简易Python服务器
2018/07/28 Python
使用django的ORM框架按月统计近一年内的数据方法
2019/07/18 Python
python经典趣味24点游戏程序设计
2019/07/26 Python
pytorch 使用加载训练好的模型做inference
2020/02/20 Python
python和c语言哪个更适合初学者
2020/06/22 Python
基于Python实现全自动下载抖音视频
2020/11/06 Python
Groupon比利时官方网站:特卖和网上购物高达-70%
2019/08/09 全球购物
试用期转正鉴定评语
2014/01/27 职场文书
低碳生活倡议书
2014/04/14 职场文书
实践单位评语
2014/04/26 职场文书
SQL优化老出错,那是你没弄明白MySQL解释计划用法
2021/11/27 MySQL
SQL Server中T-SQL标识符介绍与无排序生成序号的方法
2022/05/25 SQL Server