详解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 相关文章推荐
python递归打印某个目录的内容(实例讲解)
Aug 30 Python
python中实现延时回调普通函数示例代码
Sep 08 Python
PyQt5每天必学之事件与信号
Apr 20 Python
python Tkinter的图片刷新实例
Jun 14 Python
如何使用Flask-Migrate拓展数据库表结构
Jul 24 Python
django foreignkey外键使用的例子 相当于left join
Aug 06 Python
Python开发之基于模板匹配的信用卡数字识别功能
Jan 13 Python
基于TensorFlow的CNN实现Mnist手写数字识别
Jun 17 Python
总结Pyinstaller的坑及终极解决方法(小结)
Sep 21 Python
使用python tkinter开发一个爬取B站直播弹幕工具的实现代码
Feb 07 Python
Python制作运行进度条的实现效果(代码运行不无聊)
Feb 24 Python
Django给表单添加honeypot验证增加安全性
May 06 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
用php将任何格式视频转为flv的代码
2009/09/03 PHP
PHP删除HTMl标签的实现代码
2013/06/30 PHP
PHP实现的CURL非阻塞调用类
2018/07/26 PHP
JavaScript.The.Good.Parts阅读笔记(二)作用域&amp;闭包&amp;减缓全局空间污染
2010/11/16 Javascript
利用jq让你的div居中的好方法分享
2013/11/21 Javascript
jQuery中nextUntil()方法用法实例
2015/01/07 Javascript
在Javascript中处理字符串之big()方法的使用
2015/06/08 Javascript
jquery实现点击弹出可放大居中及关闭的对话框(附demo源码下载)
2016/05/10 Javascript
jquery移除了live()、die(),新版事件绑定on()、off()的方法
2016/10/26 Javascript
vue.js加载新的内容(实例代码)
2017/06/01 Javascript
vue.js中父组件调用子组件的内部方法示例
2017/10/22 Javascript
微信小程序实现星星评价效果
2018/11/02 Javascript
vue封装一个简单的div框选时间的组件的方法
2019/01/06 Javascript
javascript实现blob加密视频源地址的方法
2019/08/08 Javascript
wx-charts 微信小程序图表插件的具体使用
2019/08/18 Javascript
JavaScript setInterval()与setTimeout()计时器
2019/12/27 Javascript
Vue + Node.js + MongoDB图片上传组件实现图片预览和删除功能详解
2020/04/29 Javascript
使用npm命令提示: 'npm' 不是内部或外部命令,也不是可运行的程序的处理方法
2020/05/14 Javascript
bootstrap-table后端分页功能完整实例
2020/06/01 Javascript
[00:32]2016完美“圣”典风云人物:Maybe宣传片
2016/12/05 DOTA
深度剖析使用python抓取网页正文的源码
2014/06/11 Python
Python+request+unittest实现接口测试框架集成实例
2018/03/16 Python
使用Python检测文章抄袭及去重算法原理解析
2019/06/14 Python
Python使用Pandas读写Excel实例解析
2019/11/19 Python
基于CentOS搭建Python Django环境过程解析
2020/08/24 Python
Python提取视频中图片的示例(按帧、按秒)
2020/10/22 Python
真正的英国宝藏:Mappin & Webb
2019/05/05 全球购物
十八届三中全会报告学习材料
2014/02/17 职场文书
传播学专业毕业生自荐书
2014/07/01 职场文书
党的群众路线教育实践活动心得体会(企业)
2014/11/03 职场文书
幼儿园中班教师个人工作总结
2015/02/06 职场文书
导游词之秦始皇兵马俑博物馆
2019/09/29 职场文书
python requests模块的使用示例
2021/04/07 Python
解决numpy数组互换两行及赋值的问题
2021/04/17 Python
Nginx stream 配置代理(Nginx TCP/UDP 负载均衡)
2021/11/17 Servers
聊聊Python String型列表求最值的问题
2022/01/18 Python