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

如何从Python的frame对象获取列号?(已掌握行号获取方法)

获取Python Frame对象的列号信息

你提到的用sys._getframe()获取行号的方法确实实用,但Python的frame对象本身并没有直接存储列号信息,这也是官方文档里没提到列号相关属性的原因。不过我们可以通过结合源码解析和字节码分析的方式间接推导列号,下面给你两种可行的思路:

方法一:用inspect模块结合源码文本定位

既然你提到可以接受inspect.getsource(),那这个方案最直接。核心思路是通过frame拿到代码对象和行号,再获取该行源码,结合字节码偏移定位具体列位置:

import sys
import inspect
import dis

def get_frame_colno(frame):
    # 获取当前行的源码内容
    lines, start_line = inspect.getsourcelines(frame.f_code)
    target_line = lines[frame.f_lineno - start_line].strip()
    
    # 找到当前执行字节码对应的指令
    offset = frame.f_lasti
    for instr in dis.get_instructions(frame.f_code):
        if instr.offset == offset:
            # 定位指令对应的源码位置(以函数名为例)
            col = target_line.find(instr.argrepr)
            if col != -1:
                return col + 1  # 列号从1开始计数
            return None

def f():
    frame = sys._getframe(1)
    print(f"行号: {frame.f_lineno}, 列号: {get_frame_colno(frame)}")
    return 1

# 测试调用
f() + f()

运行后你会看到输出对应两个f()调用的列位置(比如第一个f()在代码行的起始列附近,第二个在加号后的位置,具体取决于你的代码缩进)。

方法二:通过字节码指令偏移量估算列号

如果不想依赖源码文件(比如处理编译后的pyc文件),可以通过分析字节码的偏移和指令长度估算列号,不过这个方法精度稍差,因为字节码和源码列号的映射不是完全一一对应的:

import sys
import dis

def get_colno_from_bytecode(frame):
    code = frame.f_code
    offset = frame.f_lasti
    col = 0
    # 统计当前偏移前的字节码指令总长度,以此估算列位置
    for instr in dis.get_instructions(code):
        if instr.offset >= offset:
            break
        col += len(instr.opname) + 2  # 简单假设每个指令占若干列
    return col

def f():
    frame = sys._getframe(1)
    print(f"行号: {frame.f_lineno}, 估算列号: {get_colno_from_bytecode(frame)}")
    return 1

f() + f()

注意事项

  • 第一种方法依赖源码文件存在,如果代码是动态生成的(比如exec执行的字符串),inspect.getsourcelines()会失败。
  • 列号的定义有歧义:是函数调用的起始列,还是参数位置?上面的示例以函数名的起始位置为准,你可以根据需求调整源码匹配逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 02:28:29