没有类型提示的代码:
def greeting(name):
return 'Hello ' + name
复制代码
有类型提示的代码:
def greeting(name: str) -> str:
return 'Hello ' + name
复制代码
提示的通用格式通常是这样:
def function(variable: input_type) -> return_type:
pass
复制代码
然而,关于他们究竟是什么(在本文中,我暂且称他们为提示)、他们会如何使你的代码受益,仍然有许多让人困惑不解的地方。
当我开始调查和衡量类型提示是否对我有用时,我变得十分困惑。所以,就像我通常对待我不理解的事情一样,我决定深入挖掘,同时也希望这篇文章对其他人有用。
像往常一样,如果你想评论你看到的某些内容,请随时 pull request.
计算机如何编译我们的代码
为了弄清楚 Python 核心开发人员在尝试用类型提示做什么,我们来从 Python 中分几个层次,从而更好地理解计算机和编程语言的工作原理。
编程语言的核心作用,是利用 CPU 进行数据处理,并把输入输出存储在内存中。
CPU 相当愚蠢,它可以完成艰巨的任务,但只能理解机器语言,其底层依靠电力驱动。机器语言底层使用 0 和 1 来表示。
为了得到这些 0 和 1,我们要从高级语言转向低级语言,这就需要编译和解释型语言了。
编程语言要么被编译要么被执行(Python 通过解释器解释执行),代码转换为较低级别的机器代码,告诉计算机的低级组件即硬件该做什么。
有多种方法可以将代码转换为机器能识别的代码:你可以构建二进制文件并让编译器对其进行翻译(C++、Go、Rust 等),或直接运行代码并让解释器执行。后者是 Python(以及 PHP、Ruby 和类似的脚本语言)的工作原理。
硬件如何知道如何将这些 0 和 1 存储在内存中?软件也就是我们的代码需要告诉硬件该如何为数据分配内存。这些数据是什么类型的呢?这就由语言选择的数据类型来决定了。
每一种语言都有数据类型,他们往往是你学习编程时的第一件要学习的事情。
你可能看过这样的教程 (来自 Allen Downey 的优秀教材,”像计算机科学家一样思考“),讲述了它们是什么。简而言之,它们是表示内存中数据的不同方式。
根据所使用语言的不同,会有字符串,整数等其他类型。比如 Python 的基本数据类型 包含:
int, float, complex
str
bytes
tuple
frozenset
bool
array
bytearray
list
set
dict
复制代码
还有由几种基本数据类型构成的高级数据类型。例如,Python 列表可以包含整数,字符串或两者都包含。
为了知道需要分配多少内存,计算机需要知道被存储数据的类型。幸运的是,Python 的内置函数 getsizeof
,可以告诉我们每种不同的数据类型占多少字节。
这个精彩的回答告诉了我们一些“空数据结构”的近似值:
import sys
import decimal
import operator
d = {"int": 0,
"float": 0.0,
"dict": dict(),
"set": set(),
"tuple": tuple(),
"list": list(),
"str": "a",
"unicode": u"a",
"decimal": d