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

Python中setattr与getattr优化:动态字典属性添加最佳实践

优化动态字典容器的add_value方法性能

需求回顾

需要实现一个Container类,支持动态创建任意数量的字典作为实例变量,用户调用add_value时无需提前检查字典是否存在,直接为指定字典追加键值对,目标效果如下:

>>> c = Container()
>>> c.add_value(variable="first_dict", key="foo", value=1)
>>> c.add_value(variable="first_dict", key="bar", value=2)
>>> c.add_value(variable="second_dict", key="foo", value=2)
>>> print(c.first_dict)
{"foo":1, "bar":2}
>>> print(c.second_dict)
{"foo":2}

原实现的性能顾虑

原实现通过getattr获取属性、修改后再用setattr赋值,确实存在额外的函数调用开销,尤其是在高频调用add_value的场景下。以下是几种更优的实现方案:


方案1:直接操作实例的__dict__属性

Python实例的所有属性都存储在__dict__字典中,直接访问它可以省去getattr和setattr的函数调用开销:

from typing import Any

class Container():
    def add_value(self, variable: str, key: Any, value: Any):
        # 从__dict__获取字典,不存在则创建空字典
        dict_obj = self.__dict__.get(variable, {})
        dict_obj[key] = value
        self.__dict__[variable] = dict_obj

说明:直接操作__dict__是性能最高的方式之一,减少了两层函数调用的开销。

方案2:利用__getattr__魔法方法延迟创建字典

通过__getattr__实现属性的延迟初始化,只有当属性不存在时才创建空字典,且因为字典是可变对象,修改后无需重新赋值:

from typing import Any

class Container():
    def __getattr__(self, name: str):
        # 访问不存在的属性时自动创建空字典
        self.__dict__[name] = {}
        return self.__dict__[name]

    def add_value(self, variable: str, key: Any, value: Any):
        # 直接获取属性(不存在则触发__getattr__创建)
        getattr(self, variable)[key] = value

说明:这个方案更符合Pythonic风格,仅在第一次访问目标字典时触发创建逻辑,后续调用直接操作字典本身,无需再调用setattr。

方案3:用内部统一字典管理所有动态字典

将所有动态字典集中存储在一个内部字典中,避免污染实例的__dict__,同时通过__getattr__保持外部访问的便利性:

from typing import Any, Dict

class Container():
    def __init__(self):
        self._dicts: Dict[str, Dict[Any, Any]] = {}

    def add_value(self, variable: str, key: Any, value: Any):
        # 一行完成"获取/创建字典 + 赋值键值对"
        self._dicts.setdefault(variable, {})[key] = value

    def __getattr__(self, name: str):
        if name in self._dicts:
            return self._dicts[name]
        raise AttributeError(f"'Container' object has no attribute '{name}'")

说明:dict.setdefault是内置高效方法,能快速完成字典的初始化和键值对赋值;集中管理的方式也让代码更易维护,比如后续可以轻松实现批量操作所有动态字典的功能。


方案对比

  • 追求极致性能:优先选择方案1或方案3
  • 追求代码优雅和可读性:方案2更合适
  • 需要集中管理动态字典:方案3是最佳选择

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:08:19