Guido van Rossum 想要在 Python 中加入类型注释

阅读数:1840 2014 年 8 月 20 日

话题:Python语言 & 开发架构

Python 编程语言的设计者Guido van Rossum,最近在 python-ideas 邮件列表中提出了一个建议:在 Python 函数声明中加入类型注释。这个建议旨在在不改变 Python 动态类型的本质和解释器行为的前提下,让 Python 获得静态类型系统所带来的好处。

其目标是,在不改变程序执行逻辑的情况下,通过(未修改的)Python 3.5 解释器运行时,能够对第三方模块(甚至是 stdlib)添加类型检查注释。

Guido 所提出的添加类型注释的建议源自于 Bob Ippolito 和 Jukka Lehtosalo 的想法。Bob Ippolito主张将 Haskell 的一些特性引入到 Python 和其他语言中。Jukka Lehtosalo 则是mypy的作者,这是一个带有试验性质的 Python 变种版本,旨在将动态类型和静态类型的好处结合起来。

Mypy 是 Guido 建议中的主要内容。在建议中,Guido 说到,可以将 mypy 看成一个用于 Python 的、类似 lint的静态检查器。用于在编译期或是在 mypy 的 Python 解释器下运行时,检查程序中类型的正确性。另一方面,程序在 Python 官方的解释器下执行时,能够不受类型注释的影响。因此也不会有运行时类型检查的开销。为了达到这一点,关键在于用于类型注释的语法必须符合 Python 3 的语法。这也是 mypy 的一个特性。实际上,mypy 在指定类型签名的时候使用了函数注释这个 Python 3 的语法。该语法允许为函数添加任意元数据注释。

作为一个 mypy 基本语义的例子,以下的 Python 定义:

def fib(n):
    a, b = 0, 1
    while a < n:
        print(a)
        a, b = b, a+b

在 mypy 中可以稍加修改以指定一个类型签名

def fib(n: int) -> None:
    a, b = 0, 1
    while a < n:
        print(a)
        a, b = b, a+b

万一没有合适的 Python 语法能够指定某个类型,那 mypy 可以使用注解的方式。Guido van Rossum 在他的建议里提供了一个这样的例子:

def word_count(input: List[str]) -> Dict[str, int]:
      result = {}  #type: Dict[str, int]
      for line in input:
          for word in line.split():
              result[word] = result.get(word, 0) + 1
      return result

鉴于所有这一切,Guido 建议可以及时地为 Python 3.5 编写,采用和实施一份 PEP。这需要完成两项工作:

  • 重新考虑函数注释的定义,将它的使用限制于类型注释。

  • 为需要加入 Python 3.5 的内容制定一个规范。Guido 建议添加的东西应越少越好。

实际的类型检查器不会被集成进 Python 解释器,也不会被签入 CPython 代码库中。唯一需要做的是在 stdlib 中加入一份 mypy 的 typing.py 模块的拷贝。这个模块定义了许多新的类(还有一些装饰器和辅助函数)。这些类可以用于表示参数的类型。如果你想要对代码进行类型检查,你需要下载和安装 mypy,并单独地运行它。

Guido 的建议在 Python-ideas 邮件列表和reddit上都引起了一些人的兴趣。除了有一些代码贡献者在讨论中表示出积极的反应外。将函数注释限制用于类型签名的指定和使用注解表达类型定义引起了一些人的担心。

查看英文原文:Guido van Rossum Wants to Bring Type Annotations to Python


感谢邵思华对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。