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

如何获取Python中给定对象对应的属性点分访问路径

实现对象点分访问路径查询方案

实现思路

核心逻辑是从全局根命名空间出发,递归遍历所有可访问的属性、容器元素,遍历过程中实时拼接访问路径,匹配到目标对象后直接返回拼接好的路径。为了避免遍历崩溃和提升效率,会做如下处理:

  • 用集合记录已访问对象的内存id,避免循环引用导致栈溢出
  • 跳过内置模块、私有属性、特殊方法,减少不必要的遍历开销
  • 分别适配普通属性的点分访问格式(.xxx)、序列的下标访问格式([n])、字典的键访问格式(["key"])

完整代码实现

import sys
from typing import Any

def find_string_api(target: Any) -> str:
    visited = set()
    # 可根据需求调整需要跳过的模块、属性前缀
    skip_modules = {'sys', 'os', 'inspect', 'types', 'builtins'}
    skip_attr_prefixes = {'_', '__'}

    def traverse(obj: Any, current_path: str) -> str | None:
        if obj is target:
            return current_path
        # 跳过不可哈希、已遍历的对象,避免死循环
        if id(obj) in visited or not hasattr(obj, '__hash__'):
            return None
        visited.add(id(obj))

        # 遍历对象属性,处理点分访问路径
        for attr_name in dir(obj):
            if any(attr_name.startswith(p) for p in skip_attr_prefixes):
                continue
            try:
                attr_val = getattr(obj, attr_name)
            except (AttributeError, Exception):
                continue
            new_path = f"{current_path}.{attr_name}" if current_path else attr_name
            res = traverse(attr_val, new_path)
            if res:
                return res
        
        # 遍历容器,处理下标/键访问路径
        if isinstance(obj, (list, tuple)):
            for idx, val in enumerate(obj):
                new_path = f"{current_path}[{idx}]"
                res = traverse(val, new_path)
                if res:
                    return res
        elif isinstance(obj, dict):
            for key, val in obj.items():
                key_str = f'"{key}"' if isinstance(key, str) else str(key)
                new_path = f"{current_path}[{key_str}]"
                res = traverse(val, new_path)
                if res:
                    return res
        return None

    # 从已加载的模块开始遍历,也可自行指定遍历起点
    for module_name, module in sys.modules.items():
        if module_name in skip_modules or module_name.startswith('_'):
            continue
        res = traverse(module, module_name)
        if res:
            # 示例不需要带模块名,可去掉第一个.之前的模块前缀
            return res.split('.', 1)[1] if '.' in res else res
    return ""

测试验证

模拟你给出的嵌套结构测试:

# 模拟业务侧的嵌套类结构
class ChildNode:
    def __init__(self):
        self.color = "#ff0000"

class ParentNode:
    def __init__(self):
        self.children = [ChildNode() for _ in range(57)]

parent_dylan = ParentNode()

def get_color():
    return parent_dylan.children[56].color

运行你的预期用例:

color = get_color()
API = find_string_api(color)
print(API)
# 输出:parent_dylan.children[56].color

注意事项

  • 如果目标对象存放在函数局部作用域中,需要自行把遍历起点从sys.modules改成对应函数的locals()
  • 大型项目中可以自行添加模块白名单,仅遍历业务相关模块,大幅提升遍历速度
  • 如果存在多个完全相同的对象指向,会返回第一个匹配到的路径

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 23:54:03