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

Python中self[name]与self.__dict__[name]的区别及AttrDict点语法解析

AttrDict代码相关问题解答

一、self.name 与 self.__dict__[name] 的区别

  1. self.name:标准属性访问语法

    • 这是Python访问实例属性的常规方式,会触发完整的属性查找流程:先检查实例自身的__dict__字典;若找不到,会依次查找类的__dict__、父类的__dict__;如果最终都找不到,还会调用重写的__getattr__方法(如果存在)。
    • 在这个AttrDict类中,当用self.name访问时,若name不在实例__dict__里,就会触发__getattr__,进而去字典的键中查找对应值。
  2. self.__dict__[name]:直接操作属性字典

    • 这是跳过属性查找流程,直接访问实例的__dict__字典(实例的所有自定义属性都存在这个字典里)。它不会触发__getattr__,也不会去类或父类的属性中查找,只针对实例自身的__dict__字典操作。
    • 比如代码中__init__方法里用self.__dict__[AttrDict.IMMUTABLE] = False,就是直接把__immutable__键值对存入实例的__dict__,避免触发属性拦截逻辑,确保这个状态标识能被正确设置和读取。

二、为何test.x = 100可以用点语法设置属性?

Python中,用点语法设置属性(obj.attr = value)会自动触发实例的__setattr__方法。这个AttrDict类重写了__setattr__,修改了默认的属性设置逻辑:

  • 执行test.x = 100时,会调用__setattr__('x', 100);
  • 方法内先判断实例是否可修改,再检查x是否在实例的__dict__中:如果不在,就执行self[name] = value,也就是把x作为字典的键、100作为对应的值存入字典;
  • 普通dict类没有重写__setattr__,默认逻辑是把属性存入实例的__dict__而非字典键值对,所以普通dict不能用点语法设置键,但AttrDict通过重写__setattr__把点语法和字典键值对操作绑定在了一起。

附原代码

class AttrDict(dict):

    IMMUTABLE = '__immutable__'

    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__[AttrDict.IMMUTABLE] = False

    def __getattr__(self, name):
        if name in self.__dict__:
            return self.__dict__[name]
        elif name in self:
            return self[name]
        else:
            raise AttributeError(name)

    def __setattr__(self, name, value):
        if not self.__dict__[AttrDict.IMMUTABLE]:
            if name in self.__dict__:
                self.__dict__[name] = value
            else:
                self[name] = value
        else:
            raise AttributeError(
                'Attempted to set "{}" to "{}", but AttrDict is immutable'.
                format(name, value)
            )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:35:20