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

如何访问名称中包含点号的Python对象属性

如何访问Bunch对象中含有点号的属性?

问题背景

我现在用Bunch类把字典转换成对象,类的代码是这样的:

class Bunch(object):
    """ Transform a dict to an object """
    def __init__(self, kwargs):
        self.__dict__.update(kwargs)

但我的字典里有个键是带点号的:{'test.this': True}。当我执行spam = Bunch({'test.this':True})后,用dir(spam)能看到对象有'test.this'这个属性,但没法用print(spam.test.this)访问它,请问该怎么解决?


解决方案

这确实是个常见的小坑——Python的属性名规则里不允许直接包含点号,所以spam.test.this会被解析成先获取spam.test属性,再尝试获取该属性的this子属性,而不是直接匹配'test.this'这个完整的属性名。给你几个不同场景下的解决办法:

1. 直接用字典式访问(无需修改Bunch类)

如果只是临时需要访问这个属性,最简单的方式是绕开点号语法,直接用__dict__或者getattr()来定位完整的属性名:

# 方式一:通过对象的__dict__字典直接取值
print(spam.__dict__['test.this'])

# 方式二:用getattr()传入完整的属性名字符串
print(getattr(spam, 'test.this'))

这种方法不需要改动原有的Bunch类,适合偶尔处理这类属性的场景。

2. 修改Bunch类,支持点号分割的属性访问

如果希望能像spam.test.this这样自然地访问,你可以重写Bunch类的__getattr__方法,让它自动处理带点号的属性名:

class Bunch(object):
    """ Transform a dict to an object, supporting dot-split key access """
    def __init__(self, kwargs):
        self.__dict__.update(kwargs)
    
    def __getattr__(self, name):
        # 先检查是否存在完整匹配的属性
        if name in self.__dict__:
            return self.__dict__[name]
        
        # 尝试按点号分割属性名,递归查找
        parts = name.split('.', 1)
        if len(parts) == 2:
            first_part, rest_part = parts
            # 优先检查是否有嵌套的Bunch对象
            if first_part in self.__dict__ and isinstance(self.__dict__[first_part], Bunch):
                return getattr(self.__dict__[first_part], rest_part)
            # 否则尝试拼接成带点号的完整键名
            full_key = f"{first_part}.{rest_part}"
            if full_key in self.__dict__:
                return self.__dict__[full_key]
        
        # 都找不到的话抛出标准的AttributeError
        raise AttributeError(f"'Bunch' object has no attribute '{name}'")

注意:如果你的字典里同时存在test(作为嵌套Bunch对象)和test.this这样的键,这个逻辑会优先匹配嵌套对象,需要根据你的实际数据结构调整优先级。

3. 预处理字典,将带点号的键转为嵌套Bunch对象

另一种更彻底的思路是在Bunch初始化时,自动把带点号的键拆分成嵌套的对象结构,比如把{'test.this': True}转换成{'test': Bunch({'this': True})},这样就能自然用点号语法访问了:

class Bunch(object):
    """ Transform a dict to an object, with nested support for dot-separated keys """
    def __init__(self, kwargs):
        for key, value in kwargs.items():
            if '.' in key:
                # 拆分键为第一层和剩余部分
                first_key, rest_key = key.split('.', 1)
                # 初始化或获取对应的嵌套Bunch对象
                if first_key not in self.__dict__ or not isinstance(self.__dict__[first_key], Bunch):
                    self.__dict__[first_key] = Bunch({})
                # 递归设置剩余的键值对
                setattr(self.__dict__[first_key], rest_key, value)
            else:
                self.__dict__[key] = value

这样处理后,spam = Bunch({'test.this': True})会自动生成嵌套结构,直接执行print(spam.test.this)就能得到True了。


内容的提问来源于stack exchange,提问作者matt.LLVW

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:19:24