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

如何在不执行代码的情况下获取Python函数的完全限定名?

获取Python函数调用的完全限定名:从AST到可行方案

我太懂这种踩坑的感觉了——原本以为用AST遍历就能搞定函数调用的完全限定名,结果真动手才发现,光是处理各种导入别名、作用域覆盖、甚至from xxx import *这种场景,就能把人折腾得头大。毕竟IDE能做“转到定义”,说明这事肯定有解,但自己从零搭AST的处理逻辑确实不现实。下面给你几个实际可行的方案:

1. 直接用成熟的静态分析库(最推荐)

别自己造轮子了!IDE的“转到定义”功能,背后依赖的就是专门做Python静态分析的工具,直接用它们就行:

  • 比如jedi:专门为代码补全、定义跳转设计的库,能自动处理绝大多数静态可解析的场景,包括导入别名、局部作用域、嵌套模块等。
    举个简单的实现示例:
    import jedi
    
    # 你的待分析代码
    code = """
    from my_module.utils import fib
    result = fib(100)
    """
    
    # 初始化jedi脚本对象
    script = jedi.Script(code)
    # 获取所有引用节点
    references = script.get_references()
    
    for ref in references:
        # 筛选出函数调用的节点
        if ref.type == 'function' and ref.name == 'fib':
            print(ref.full_name)  # 输出:my_module.utils.fib
    
    它甚至能处理from my_module import *这种模糊导入,只要符号能被静态解析,就能给出正确的完全限定名。

2. 用Astroid增强AST分析(进阶)

如果不想引入太重的依赖,或者需要和AST流程结合,可以用astroid——它是pylint的核心静态分析库,对原生AST做了扩展,自带符号表和类型推断能力。
示例代码:

import astroid

code = """
import my_module
result = my_module.fib(100)
"""

# 解析代码生成增强版AST树
tree = astroid.parse(code)
# 定位到函数调用节点(这里假设第二个语句是调用)
call_node = tree.body[1].value

try:
    # 推断函数的定义对象
    inferred_objs = call_node.func.infer()
    for obj in inferred_objs:
        if isinstance(obj, astroid.FunctionDef):
            print(obj.qname)  # 输出:my_module.fib
except astroid.InferenceError:
    # 处理无法静态推断的情况(比如动态导入、运行时修改的符号)
    print("无法推断该函数的完全限定名")

Astroid已经帮你处理了很多AST原生没有的符号跟踪逻辑,比自己手写符号表省力太多。

3. 手动基于AST+符号表实现(不推荐)

如果非要自己从零实现,核心是维护一个嵌套的符号表,跟踪每个作用域内的符号来源:

  • 遍历AST时,为每个作用域(模块、函数、类)创建一个符号表项,记录符号的映射关系(比如别名对应的原始完全限定名)
  • 处理导入语句时,把import x as y、from x import z as w这类别名和原始路径关联起来
  • 遇到函数调用节点(比如你给出的Call(func=Name(id='fib', ...))时,从当前作用域往上递归查找符号的定义,直到找到对应的完全限定名

但要注意:这种方法只能处理静态可解析的场景,遇到动态导入(比如__import__('foo'))、运行时修改的符号(比如fib = other_func)就无能为力了,而且需要覆盖大量边缘案例,工作量极大。


你给出的函数调用节点示例:

Call(func=Name(id='fib', ctx=Load()), args=[ Num(n=100), ], keywords=[])

这个节点本身只包含fib这个短名,要得到完全限定名,必须结合上下文的导入、作用域信息——这也是原生AST单独做不到的核心原因,必须依赖符号跟踪或者静态分析工具。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:05:35