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

如何创建支持属性式与字典式访问的Python对象?

实现同时支持属性访问与字典键访问的Python对象

要实现类似xarray Dataset的双访问模式,核心是让对象同时支持属性式访问(.var)和字典键式访问(['var']),下面提供两种实用的实现方案:

方案一:继承dict并重写属性访问方法

利用dict本身的字典访问能力,仅需补充属性访问的逻辑:

class DualAccessDict(dict):
    def __getattr__(self, name):
        # 当属性访问失败时,尝试从字典键中获取
        try:
            return self[name]
        except KeyError:
            raise AttributeError(f"'DualAccessDict' object has no attribute '{name}'") from None

    def __setattr__(self, name, value):
        # 优先处理字典键,避免覆盖类的内置方法(如keys()、items())
        if name in self or name not in dir(self):
            self[name] = value
        else:
            # 若为类本身的属性,调用父类方法设置
            super().__setattr__(name, value)

    def __delattr__(self, name):
        # 优先删除字典键,失败则删除实例属性
        try:
            del self[name]
        except KeyError:
            super().__delattr__(name)

使用示例

dd = DualAccessDict()
dd['var1'] = 100
print(dd.var1)  # 输出: 100

dd.var2 = 200
print(dd['var2'])  # 输出: 200

del dd.var1
print('var1' in dd)  # 输出: False

方案二:自定义类维护内部字典(更灵活)

如果不想继承dict,可自行维护内部数据字典,实现完整的映射协议:

class DualAccessObject:
    def __init__(self, **kwargs):
        self._data = kwargs

    # 实现字典键访问
    def __getitem__(self, key):
        return self._data[key]

    def __setitem__(self, key, value):
        self._data[key] = value

    def __delitem__(self, key):
        del self._data[key]

    # 实现属性访问
    def __getattr__(self, name):
        try:
            return self._data[name]
        except KeyError:
            raise AttributeError(f"'DualAccessObject' object has no attribute '{name}'") from None

    def __setattr__(self, name, value):
        # 区分内部属性与数据键,避免递归问题
        if name == '_data':
            super().__setattr__(name, value)
        else:
            self._data[name] = value

    def __delattr__(self, name):
        if name == '_data':
            super().__delattr__(name)
        else:
            try:
                del self._data[name]
            except KeyError:
                raise AttributeError(f"'DualAccessObject' object has no attribute '{name}'") from None

    # 可选:添加字典常用方法,提升兼容性
    def keys(self):
        return self._data.keys()

    def items(self):
        return self._data.items()

    def values(self):
        return self._data.values()

    # 可选:让IDE自动补全能识别数据键
    def __dir__(self):
        return super().__dir__() + list(self._data.keys())

使用示例

obj = DualAccessObject(var1=10)
print(obj.var1)       # 输出: 10
print(obj['var1'])    # 输出: 10

obj.var2 = 20
print(obj['var2'])    # 输出: 20

del obj.var1
print('var1' in obj._data)  # 输出: False

注意事项

  • 避免数据键与类内置方法重名(如keys、items),否则属性访问会优先调用类方法而非数据键。若需支持此类场景,可重写__getattribute__方法(需注意递归陷阱)。
  • 若要完全模拟xarray的行为,可额外实现__repr__、__len__等方法,优化对象的打印与交互体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 07:20:06