在PyCharm中查看源代码的时候,发现有些代码行有星号(*)标识,鼠标移上去会提示在某个.pyi文件中有其存根程序,点击星号会跳转到对应的存根程序处。

【PEP 484】.pyi文件_Python

 那什么是存根程序呢?

我第一次看到这个概念是在软件工程的书里,它主要就是用来做集成测试的。比如下图中M是实际开发出来的模块,S就是存根程序(一个临时文件,用来模拟实际的模块,向要测试的模块发送它们需要的消息)。这样的好处就是可以逐步完成整个大项目的测试。

【PEP 484】.pyi文件_pyi_02

 那么在我这个例子的Python源码中,.pyi存根文件起到了什么作用呢?

在网上查询的时候,有人推荐了PEP 484文档。484中的原话是这样的:

This PEP introduces a provisional module to provide these standard definitions and tools, along with some conventions for situations where annotations are not available.

简言之,484提供了临时性的一个模块(即存根文件),对一些目前注解没有明确定义的地方给出自己的补充。

我个人理解484整体目的就是为了帮助用户进行类型检查。Python本身是动态语言,不像静态语言可以在编译的时候进行类型检查,所以484通过这种存根文件、注解这些东西可以辅助用户在编写代码时给出建议的类型提示,不仅可以用IDE更快速地进行开发,还能减少运行时的类型报错。例如:

1)因为在.pyi文件中有相关类型定义,所以在敲代码时会出现提示。

【PEP 484】.pyi文件_python_03

2)如果输入类型与.pyi冲突,IDE的Type checker会给出警告信息,减少类型报错。

【PEP 484】.pyi文件_编写代码_04

注意: ①.pyi文件只针对Type checker有用;②Type checker的设置是可以自己修改的,比如修改类型报错等级,或是对此根本不进行类型检查等等(如下图)

【PEP 484】.pyi文件_初始化_05

怎么使用.pyi文件呢?

举个简单的例子:

自定义一个类,其中的年龄属性要求初始化的数据为整数。

module1.py:

class A:

def __init__(self, age):

self.age = age

module1.py:

class A:

def __init__(self, age : int = ...) -> None: ...

当初始化对象的年龄为float时,出现警告信息,提示应为int类型: 

【PEP 484】.pyi文件_pyi_06