字典属性化访问Dict2Obj & __setattr__的思考
class B:
def __setattr__(self,key,value):
pass
raise NotImplementedError
类方法__setattr__覆盖父类方法后,如果为pass, raise NotImplementedError之类的,则实例不能设置任何属性
pass不会报错,raise NotImplementedError会抛异常
但是类可以继续增加属性,__setattr__为实例方法
但是实例的__dict__为一个空dict,这是__new__方法创建实例的时候已经创建好的,在__setattr__之前,
所以可以通过直接操作实例的__dict__来变相添加属性
1 2 3 4 5 6 7 | class B: def __setattr__(self,key,value): raise NotImplementedError( '{} can\'t set attribute!' .format(self)) b=B() print(b.__dict__) b.a=33 |
class B:
def __setattr__(self,key,value):
raise NotImplementedError('{} can\'t set attribute!'.format(self))
b=B()
print(b.__dict__)
b.__dict__['v']=33
print(b.__dict__)
print(b.v)
class Dict2Obj(object):
def __init__(self,d:dict):
# self._dict=d
self.__dict__={'_dict':d}
# self.b=33
def __getattr__(self,item):
try:
# def __setattr__: pass,I.__dict__ == {},取self._dict时,又会调用__getattr__
return self._dict[item]
# return getattr(self._dict,item) # AttributeError: 'dict' object has no attribute 'b'
# return getattr(self,item) # 本身就是.访问
except KeyError:
raise AttributeError('Attribute {!a:} not found!'.format(item))
def __setattr__(self,key,value):
pass
上面的会产生循环调用
self._dict=d
self.__dict__={'_dict':d}
self.b=33
都会调用__setattr__,不会产生作用
getattr(object,name,default=None) 内置函数也是调用__getattr__
self._dict[item]本身就是访问实例属性
Corrent Sample:
d={
'b':22,
'bb':33
}
class Dict2Obj(object):
def __init__(self,d:dict):
# self.__dict__={'_dict':d} # 覆盖实例创建时的字典,依然会调用__setattr__
if not isinstance(d,(dict,)):
self.__dict__['_dict']={}
else:
self.__dict__['_dict']=d
def __getattr__(self,item):
try:
return self._dict[item]
except KeyError:
raise AttributeError('Attribute {} not found!'.format(item))
def __setattr__(self,key,value):
raise NotImplementedError
b=Dict2Obj(d)
print(b.__dict__)
print(b.b,b.bb)
不允许动态增加属性,通过__dict__依然可以增加,不提倡
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律