You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Astroid通过类型注解推断函数参数的类型?

Astroid类型注解推断问题的解决办法

问题背景

我正尝试使用Astroid为Pylint编写自定义lint规则,但在类型推断方面遇到了问题。代码示例:

class ProtectedObject:
    def save():
        pass
                
def save_protected_object(obj: ProtectedObject) -> None:
    obj.save()

通过astroid.extract_node(code)成功获取到save_protected_object对应的FuncDef节点,但Astroid无法识别参数obj的类型注解,调用func.args.args[0].infer()返回Uninferable。

可行解决方案

方案1:启用全局类型注解支持

Astroid默认未开启类型注解的自动推断,需手动开启use_type_annotations配置:

import astroid

# 开启类型注解推断
astroid.MANAGER.config.use_type_annotations = True

code = """
class ProtectedObject:
    def save():
        pass
                
def save_protected_object(obj: ProtectedObject) -> None:
    obj.save()
"""

# 提取函数节点
func = astroid.extract_node(code + "\nsave_protected_object")
param = func.args.args[0]

# 推断参数类型
inferred_types = list(param.infer())
# 此时inferred_types会包含ProtectedObject对应的类节点

方案2:手动解析参数的注解节点

若全局配置不合适,可直接从参数节点的annotation属性获取注解,再单独推断注解的类型:

import astroid

code = """
class ProtectedObject:
    def save():
        pass
                
def save_protected_object(obj: ProtectedObject) -> None:
    obj.save()
"""

func = astroid.extract_node(code + "\nsave_protected_object")
param = func.args.args[0]

# 获取并推断注解类型
if param.annotation:
    inferred_annotation = list(param.annotation.infer())
    # inferred_annotation将返回ProtectedObject的类节点

对于泛型、Union这类复杂类型注解,需要额外处理逻辑,但简单类类型注解用上述方法即可解决问题。

内容的提问来源于stack exchange,提问作者unpollito

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 17:41:07