pyi 文件

.pyi 文件是 Python 的存根文件(Stub Files),用于为 Python 模块提供类型提示信息(Type Hints),而不影响运行时的行为。它是 Python 类型系统(PEP 484、PEP 526 等)的一部分,主要用于支持静态类型检查工具如 mypy、PyCharm、VS Code 等 IDE 的智能提示和类型分析。


📌 .pyi 文件的作用

  1. 分离类型信息与实现代码

    • 可以将类型注解从运行时代码中分离出来,避免污染 .py 文件。
    • 特别适用于遗留项目或 C 扩展模块(如标准库中的 os.pyisys.pyi)。
  2. 支持第三方库的类型提示

    • 如果某个库本身没有提供类型提示,可以通过 .pyi 文件为其添加类型信息。
    • 例如:typeshed 项目就是 Python 官方维护的一个大型 .pyi 存储库,包含了标准库和一些内置模块的类型信息。
  3. 提高可维护性

    • 在团队开发中,使用 .pyi 文件可以更容易地管理和版本控制类型信息。

🧱 .pyi 文件的结构

.pyi 文件的语法与普通 .py 文件非常相似,但只包含函数签名、类定义、变量类型等类型信息,不包含实际的实现逻辑。

示例:

原始 .py 文件:
# my_module.py
def greet(name):
    print(f"Hello, {name}")
对应的 .pyi 文件:
# my_module.pyi
def greet(name: str) -> None: ...

注意:

  • 使用 ... 表示该函数没有实际体(即只是声明)。
  • 所有变量、函数、类都必须带有类型信息。

.pyi 文件的命名和位置

  • 通常与对应的 .py 文件同名,扩展名为 .pyi
  • 放在与 .py 文件相同目录下,或者放在特定的类型目录中(如 stubs/)。
  • 当使用类型检查器(如 mypy)时,会自动查找并加载这些文件。

🔍 示例:为类添加类型信息

.py 文件:
# person.py
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say_hello(self):
        print(f"Hello, I'm {self.name}")
.pyi 文件:
# person.pyi
class Person:
    name: str
    age: int

    def __init__(self, name: str, age: int) -> None: ...
    def say_hello(self) -> None: ...

🛠️ 如何使用 .pyi 文件

  1. 安装类型检查工具(如 mypy)

    pip install mypy
    
  2. 运行类型检查

    mypy my_module.py
    

    mypy 会自动读取同目录下的 .pyi 文件进行类型检查。

  3. IDE 支持

    • VS Code(配合 Pylance)
    • PyCharm
    • 其他现代 Python 编辑器都支持 .pyi 文件中的类型提示。

🧩 更复杂的例子(含泛型、协议等)

# example.pyi
from typing import List, TypeVar, Protocol

T = TypeVar("T")

class HasLength(Protocol):
    def __len__(self) -> int: ...

def process(items: List[T]) -> T: ...
def get_length(obj: HasLength) -> int: ...

📅 关键时间线

时间版本事件
2014 年N/APEP 484 提案开始讨论,提出使用类型提示的标准方式,并首次提到使用 .pyi 存根文件用于分离类型信息与实现。
2015 年 9 月Python 3.5PEP 484 被接受并合入 Python 3.5,这是类型提示正式进入 Python 的起点。虽然 .pyi 不是语言特性本身的一部分,但它是 PEP 484 推荐的用法之一。
2016 年mypy 0.4.x+mypy 等静态类型检查工具开始广泛支持 .pyi 文件。
2017 年Python 3.6PEP 526 引入变量注解语法(如 x: int = 1),进一步丰富了类型系统生态,也增强了 .pyi 文件的能力。
2018 年PEP 561PEP 561 正式规范了如何为第三方库打包和分发类型信息(通过 .pyi 文件或 Typed 包标记)。这是 .pyi 文件被正式纳入生态系统标准的重要一步。

✅ 支持 .pyi 文件的 Python 版本

虽然 .pyi 文件不是 Python 解释器直接使用的功能(它们主要用于类型检查工具),但为了使用完整的类型提示语法,推荐使用以下版本:

功能建议最低 Python 版本
基础类型提示(函数参数、返回值)Python 3.5
变量注解(PEP 526)Python 3.6
支持 from typing import * 的完整特性Python 3.5+
支持 TypedDictProtocol 等高级特性Python 3.8(通过 typing_extensions 可向后兼容)
PEP 561(发布类型信息包)Python 3.5+(工具支持为主)

🧩 工具对 .pyi 的支持

工具是否支持 .pyi
mypy✅ 完全支持
pyright / Pylance(VS Code)✅ 完全支持
PyCharm✅ 支持良好
pytype(Google)✅ 支持
Jedi(代码补全)⚠️ 部分支持

🔚 总结

问题回答
.pyi 是从哪个 Python 版本开始支持的?没有具体“开始支持”的版本,它是随类型提示(PEP 484)一起出现的,Python 3.5 是第一个支持完整类型提示语法的版本。
我应该使用哪个 Python 版本来配合 .pyi推荐使用 Python 3.9 或更高版本,以获得最全面的类型系统支持。
.pyi 是官方支持的吗?是的,PEP 561 正式将其纳入 Python 生态系统标准。

📚 相关资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值