如何通过Pylance/Pyright程序化提取Python项目类型信息?
程序化提取Python代码变量类型:基于Pyright/Pylance的实现方案
针对你需要提取代码中变量推断类型的需求,以下是几种可行的实现方案,优先基于Pyright(Pylance的核心引擎)来实现:
方案一:Pyright CLI + JSON输出(最简单易实现)
Pyright提供了CLI工具,支持以JSON格式输出代码的完整类型分析结果,你可以通过解析JSON提取目标变量的类型信息。
步骤:
- 安装Pyright:
# 两种安装方式选其一 npm install -g pyright # 基于Node.js环境 # 或用Python封装版 pip install pyright - 运行Pyright分析目标文件并输出JSON:
pyright --outputjson your_code.py > analysis_result.json - 用Python解析JSON结果,提取目标变量类型:
import json with open('analysis_result.json', 'r') as f: data = json.load(f) # 遍历文件符号信息,找到目标变量 for file_data in data['files']: if file_data['file'] == 'your_code.py': for symbol in file_data['symbols']: # 匹配示例中的person变量 if symbol['name'] == 'person' and symbol['kind'] == 'variable': print(f"变量person的类型:{symbol['type']}") # 输出结果:变量person的类型:Person
方案二:直接调用Pyright的Node.js API(深度定制)
如果你需要更灵活的类型分析逻辑,可以直接调用Pyright的内部Node.js API,直接访问其类型检查引擎的结果。
示例TypeScript脚本:
import { createProgram, Program } from 'pyright'; // 创建Pyright程序实例 const program: Program = createProgram({ rootPath: './', fileNames: ['your_code.py'], // 可配置类型检查选项,比如严格模式等 options: { strict: true } }); // 获取目标文件的符号信息 const sourceFile = program.getSourceFile('your_code.py'); if (sourceFile) { const symbols = program.getSymbolsInFile(sourceFile); symbols.forEach(symbol => { if (symbol.name === 'person' && symbol.kind === 'variable') { console.log(`变量person的类型:${symbol.type}`); } }); }
运行前需确保已安装Pyright依赖:npm install pyright,然后用ts-node执行脚本。
方案三:通过LSP客户端调用Pylance/Pyright(完整复用Pylance能力)
Pylance基于LSP(语言服务器协议)运行,你可以通过搭建LSP客户端,发送请求获取类型信息。
示例Python客户端代码(基于pygls):
from lsprotocol.types import ( InitializeParams, TextDocumentItem, DidOpenTextDocumentParams, HoverParams, Position, ) from pygls.client import JsonRPCClient # 连接Pylance服务器(需先启动Pylance服务,可从VS Code安装目录找到pylance可执行文件) client = JsonRPCClient() client.connect('tcp://localhost:5007') # 发送初始化请求 init_params = InitializeParams( process_id=123, root_uri='file:///path/to/your/project/directory' ) client.send_request('initialize', init_params) # 打开目标文件 doc_path = 'your_code.py' with open(doc_path, 'r') as f: doc_text = f.read() doc = TextDocumentItem( uri=f'file:///{doc_path}', language_id='python', version=1, text=doc_text ) client.send_notification('textDocument/didOpen', DidOpenTextDocumentParams(text_document=doc)) # 请求变量person的类型(对应示例代码中person = Person(...)的行,行号从0开始) hover_params = HoverParams( text_document=doc, position=Position(line=14, character=4) ) result = client.send_request('textDocument/hover', hover_params) # 解析hover结果中的类型信息 print(f"变量person的类型:{result.contents.value.split('```')[1].strip()}") # 关闭连接 client.send_request('shutdown') client.send_notification('exit')
方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| Pyright CLI+JSON | 实现简单,无需额外编程 | 灵活性有限,依赖JSON解析 |
| Pyright Node.js API | 高度灵活,直接访问引擎 | 需要Node.js开发环境 |
| LSP客户端 | 完全复用Pylance的能力 | LSP协议复杂,调试成本高 |
排除方案说明
- 手动AST解析:仅能提取显式类型注解,无法获取Pyright的推断类型,不符合需求。
- mypy API:虽然提供程序化能力,但类型推断精度不如Pyright/Pylance,不推荐。
内容的提问来源于stack exchange,提问作者Exploring
相关产品推荐
相关产品推荐

