前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单聊聊Python的类型系统

简单聊聊Python的类型系统

作者头像
哒呵呵
发布2019-01-23 16:46:23
1.2K0
发布2019-01-23 16:46:23
举报
文章被收录于专栏:鸿的学习笔记

编译自https://realpython.com/python-type-checking/

这篇文章实际是The Ultimate Guide to Python Type Checking文的导读和个人理解,有不当之处,以原文为准。内容分为四个部分:

  • 类型注解和提示(Type annotations and type hints)
  • 代码里添加静态类型
  • 静态类型检查
  • 运行时强制类型一致

Hello Type!

动态类型

任何语言都有类型系统,Python也不例外。Python的类型和一般的动态语言一样,运行时检查和变量类型可以发生改变

当一个int类型和str相加时会抛出运行错误,但是如果不运行这段代码,Python便不会报错。

代码语言:javascript
复制
>>> 1 + "two"  # Now this is type checked, and a TypeError is raised
TypeError: unsupported operand type(s) for +: 'int' and 'str'

同一个变量可以有不同的类型

代码语言:javascript
复制
>>> thing = "Hello"
>>> type(thing)
<class 'str'>

>>> thing = 28.1
>>> type(thing)
<class 'float'>
静态类型

与动态类型相反,静态类型检查可以不需要程序运行,在编译阶段就可以发现类型错误,例如Java和C语言。

代码语言:javascript
复制
String thing;
thing = "Hello";

此时thing这个变量已经确定为String类型,便不可再发生变化,并且thing也不能赋值为其他类型。

Python的抉择

虽然Python在PEP 3107(https://www.python.org/dev/peps/pep-3107/)第一次引入了函数注解,可以在函数中标记变量类型,并在PEP 484(https://www.python.org/dev/peps/pep-0484/)中由Guido(Python创始人)等继续引入类型提示,但是Python会一直是动态语言(https://www.python.org/dev/peps/pep-0484/#non-goals),类型不会影响Python的实际运行。

既然Python引入了静态类型系统,有什么影响呢? 先谈优点:

  • 方便记录代码,生成相应的文档。
  • 改善IDE和linters,藉由类型检查可以帮助开发者发现类型错误。
  • 最重要的在于大型项目可以获得更好、更干净的架构,减少开发者的失误。

作为动态语言引入类型检查,自然不会只有好处。

  • 类型的加入需要花费开发者更多的时间
  • 类型提示只适合于Python3.X以上,函数注解适用于3.X和2.7,并不能向后兼容
  • 如果使用typing(https://docs.python.org/3/library/typing.html)包,本来就慢的Python就更慢了。

作为一个对开发者友好的编程语言,Python也支持渐进式的给项目加入类型系统(https://www.python.org/dev/peps/pep-0483/)。接下来更深入的了解Python类型系统

如何使用类型系统

从一个简单的代码开始:

代码语言:javascript
复制
def headline(text, align=True):
    if align:
        return f"{text.title()}\n{'-' * len(text)}"
    else:
        return f" {text.title()} ".center(50, "o")

运行如下:

代码语言:javascript
复制
>>> print(headline("python type checking"))
Python Type Checking
--------------------

>>> print(headline("python type checking", align=False))
oooooooooooooo Python Type Checking oooooooooooooo

补充上类型注解:

代码语言:javascript
复制
def headline(text: str, align: bool = True) -> str:
    ...
代码语言:javascript
复制

这时text: str表示text这个变量应该是str类型,同样的align是bool类型,二headline函数返回的结果为str类型。当然此时违反给定的类型传入,这段代码也是可以运行的:

代码语言:javascript
复制
>>> print(headline("python type checking", align="left"))
Python Type Checking
--------------------

Python里支持类型检查的主要是Mypy包(Python的类型体系也来源于这个博士项目),除此之外还有谷歌的pytype(https://github.com/google/pytype)和Facebook的Pyre(https://pyre-check.org/)。本文主要介绍mypy包的使用。将上述代码改写进headline.py文件中:

代码语言:javascript
复制
# headlines.py
 2 
 3 def headline(text: str, align: bool = True) -> str:
 4     if align:
 5         return f"{text.title()}\n{'-' * len(text)}"
 6     else:
 7         return f" {text.title()} ".center(50, "o")
 8 
 9 print(headline("python type checking"))
10 print(headline("use mypy", align="center"))

运行:

代码语言:javascript
复制
$ mypy headlines.py
headlines.py:10: error: Argument "align" to "headline" has incompatible
                        type "str"; expected "bool"

此时mypy会报错在第十行类型错误,此时将print(headline("use mypy", align="center"))改成print(headline("use mypy", align=True))运行便会正常。

代码语言:javascript
复制
$ mypy headlines.py
$ 

运行时检查

虽说Python永远不会改变其动态语言本质,但是依然有一些包支持运行时类型错误便会报错,例如Enforce(https://pypi.org/project/enforce/), Pydantic(https://pypi.org/project/pydantic/),或者是Pytypes(https://pypi.org/project/pytypes/)。毕竟所有的类型都会存储在annotations中。

结尾

Python的类型系统介绍就到此结束了,作为Python3引入的新特性,让Python在大型项目中更加游刃有余。

相关的学习可以参考: https://github.com/Bogdanp/cursive_re/blob/master/cursive_re/exprs.py 一个很好的学习如何使用类型提示的材料 https://www.bernat.tech/the-state-of-type-hints-in-python/ 更深入的理解类型提示

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-01-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Hello Type!
    • 动态类型
      • 静态类型
      • Python的抉择
      • 如何使用类型系统
      • 运行时检查
      • 结尾
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档