Python3 类型标注支持操作


Posted in Python onJune 02, 2021

typing为Python的一个标注库,此默认支持PEP 484和PEP 526指定的类型提示。最基本的支持由Any、Union、Tuple、Callable、TypeVar和Generic类型组成。

有关完整的规范,请参阅PEP 484,有关任何类型提示的简单介绍,请参阅PEP 483。

举个栗子,函数接收并返回一个字符串,如下所示:

def func(name: str) -> str:
    return "Hello" + name

在函数func中,参数预期是str类型,并且返回str类型

typing模块的作用:

类型检查,防止运行时出现参数和返回值类型不符合

作为开发文档附加说明,方便使用者调用传入和返回类型

该模块加入之后并不会影响程序的运行,不会报正式的错误,只有提醒

类型别名

类型别名通过将类型分配别名来进行定义,在这个例子中,Vector和List[str]可以视为可互换的同义词:

from typing import List
Vector = List[str]
def func(name: str) -> Vector:
    return [name]
print(Vector, type(Vector))         # typing.List[str] <class 'typing.GenericMeta'>
value = func("laozhang")
print(value, type(value))           # ['laozhang'] <class 'list'>

NewType

使用NewType()辅助函数来创建不同的类型

from typing import NewType
UserId = NewType("UserId", int)
UserName = NewType("UserName", str)

静态类型检查器会将新类型视为它最原始类型的子类,这对于捕捉逻辑错误非常有用:

def from_int_to_str(user_id: UserId) -> str:
    return str(user_id)
    
print(from_int_to_str(UserId(123)))     # 123
print(from_int_to_str(123))             # 123

你仍然可以对UserId类型的变量执行所有的int支持的操作,但结果将始终为int类型,如下:

value = UserId(123) + UserId(456)
print(value)            # 579
print(type(value))      # <class 'int'>

值得注意的是,UserId = NewType("UserId", int),UserId是一个函数,该函数将会立即返回你传递给它的任何参数。这也意味着,无法创建UserId的子类型,因为它是运行时的标识函数,而不是实际类型,下面这种写法是错误的:

class MyUser(UserId):
    pass

但是,可以基于UserId创建NewType,如下:

ChildUserId = NewType("ChildUserId", UserId)

Callable

期望特定签名的回调函数可以将类型标注为Callable[[Arg1Type, Arg2Type], ReturnType]。例如:

from typing import Callable
def finder(on_success: Callable[[str, int], None]) -> None:
    pass  
def on_success(s: str, i: int) -> None:
    pass
finder(on_success=on_success)

如果传递过去的回调函数中的参数或返回类型不匹配,PyCharm将会有警告提示

泛型(Generics)

泛型可以使用typing模块中名为TypeVar的新工厂进行参数化,如下:

from typing import TypeVar
T = TypeVar("T")
def finder(s: T) -> T:
    return s

泛型类型可以有任意数量的类型变量,这样的话类型变量可能会收到限制:

from typing import TypeVar
T = TypeVar("T", int, str)
def finder(s: T) -> T:
    return s

这样的话,finder函数将只能接收int/str类型的参数,否则将会有警告提示

typing模块常用类型

int,、float: 整形、浮点型

bool、str: 布尔型、字符串类型

List、Dict、Tuple、Set: 列表、字典、元组、集合

Iterable、Iterator: 可迭代类型、迭代器类型

Generator: 生成器类型

更多关于typing模块的使用:https://docs.python.org/zh-cn/3.7/library/typing.html

Python 3 新特性:类型注解

前几天有同学问到,这个写法是什么意思:

def add(x:int, y:int) -> int:
    return x + y

 

我们知道 Python 是一种动态语言,变量以及函数的参数是不区分类型。因此我们定义函数只需要这样写就可以了:

def add(x, y):
    return x + y

这样的好处是有极大的灵活性,但坏处就是对于别人代码,无法一眼判断出参数的类型,IDE 也无法给出正确的提示。

于是 Python 3 提供了一个新的特性:

函数注解

也就是文章开头的这个例子:

def add(x:int, y:int) -> int:
    return x + y

 

用 : 类型 的形式指定函数的参数类型,用 -> 类型 的形式指定函数的返回值类型。

然后特别要强调的是,Python 解释器并不会因为这些注解而提供额外的校验,没有任何的类型检查工作。也就是说,这些类型注解加不加,对你的代码来说没有任何影响:

Python3 类型标注支持操作

输出:

Python3 类型标注支持操作

但这么做的好处是:

让别的程序员看得更明白

让 IDE 了解类型,从而提供更准确的代码提示、补全和语法检查(包括类型检查,可以看到 str 和 float 类型的参数被高亮提示)

Python3 类型标注支持操作

在函数的 __annotations__ 属性中会有你设定的注解:

Python3 类型标注支持操作

输出:

Python3 类型标注支持操作

在 Python 3.6 中,又引入了对变量类型进行注解的方法:

a: int = 123
b: str = 'hello'

更进一步,如果你需要指明一个全部由整数组成的列表:

from typing import List
l: List[int] = [1, 2, 3]

但同样,这些仅仅是“注解”,不会对代码产生任何影响。

不过,你可以通过 mypy 库来检验最终代码是否符合注解。

安装 mypy:

pip install mypy

执行代码:

mypy test.py

如果类型都符合,则不会有任何输出,否则就会给出类似输出:

Python3 类型标注支持操作

这些新特性也许你并不会在代码中使用,不过当你在别人的代码中看到时,请按照对方的约定进行赋值或调用。

当然,也不排除 Python 以后的版本把类型检查做到解释器里,谁知道呢。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中的自定义函数学习笔记
Sep 23 Python
Python的for和break循环结构中使用else语句的技巧
May 24 Python
Pycharm学习教程(2) 代码风格
May 02 Python
Python实现随机创建电话号码的方法示例
Dec 07 Python
PythonWeb项目Django部署在Ubuntu18.04腾讯云主机上
Apr 01 Python
Django中使用haystack+whoosh实现搜索功能
Oct 08 Python
tensorflow没有output结点,存储成pb文件的例子
Jan 04 Python
python读取多层嵌套文件夹中的文件实例
Feb 27 Python
Python bytes string相互转换过程解析
Mar 05 Python
基于python实现生成指定大小txt文档
Jul 20 Python
python 实现围棋游戏(纯tkinter gui)
Nov 13 Python
Python的logging模块基本用法
Dec 24 Python
python 实现两个变量值进行交换的n种操作
聊聊Python中关于a=[[]]*3的反思
python内置进制转换函数的操作
Jun 02 #Python
Python 内置函数速查表一览
Jun 02 #Python
利用Python判断你的密码难度等级
Jun 02 #Python
Python标准库之typing的用法(类型标注)
只用50行Python代码爬取网络美女高清图片
You might like
php中多维数组按指定value排序的实现代码
2014/08/19 PHP
php中get_defined_constants函数用法实例分析
2015/05/12 PHP
Chrome中JSON.parse的特殊实现
2011/01/12 Javascript
jQuery弹出层始终垂直居中相对于屏幕或当前窗口
2013/04/01 Javascript
javascript检测浏览器的缩放状态实现代码
2014/09/28 Javascript
JavaScript实现网页截图功能
2014/10/16 Javascript
Javascript通过overflow控制列表闭合与展开的方法
2015/05/15 Javascript
jquery实现的树形目录实例
2015/06/26 Javascript
JS中动态创建元素的三种方法总结(推荐)
2016/10/20 Javascript
微信小程序进行微信支付的步骤昂述
2016/12/01 Javascript
Bootstrap CSS布局之图像
2016/12/17 Javascript
使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
2017/03/15 Javascript
微信小程序页面传值实例分析
2017/04/19 Javascript
angularJs的ng-class切换class
2017/06/23 Javascript
浅谈Vue.js 1.x 和 2.x 实例的生命周期
2017/07/25 Javascript
浅谈Node.js 沙箱环境
2018/05/15 Javascript
微信小程序仿朋友圈发布动态功能
2018/07/15 Javascript
JS div匀速移动动画与变速移动动画代码实例
2019/03/26 Javascript
解决layUI的页面显示不全的问题
2019/09/20 Javascript
vue项目中使用particles实现粒子背景效果及遇到的坑(按钮没有点击响应)
2020/02/11 Javascript
详解阿里Node.js技术文档之process模块学习指南
2021/01/04 Javascript
[01:48:04]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第一场 2月7日
2021/03/11 DOTA
python轻松查到删除自己的微信好友
2016/01/10 Python
利用Python获取赶集网招聘信息前篇
2016/04/18 Python
利用python对excel中一列的时间数据更改格式操作
2020/07/14 Python
Web时代变迁及html5与html4的区别
2016/01/06 HTML / CSS
欧洲著名的珠宝和手表网上商城:uhrcenter
2017/04/10 全球购物
Charles&Keith美国官方网站:新加坡快时尚鞋类和配饰零售商
2019/11/27 全球购物
日本最大的彩色隐形眼镜销售网站:CharmColor
2020/09/09 全球购物
武汉瑞得软件笔试题
2015/10/27 面试题
医学生求职自荐信
2013/10/25 职场文书
降消项目实施方案
2014/03/30 职场文书
119消防日活动总结
2014/08/29 职场文书
入队仪式主持词
2015/07/04 职场文书
SQL实现LeetCode(196.删除重复邮箱)
2021/08/07 MySQL
java多态注意项小结
2021/10/16 Java/Android