ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

字典属性化访问Dict2Obj & __setattr__的思考

2020-11-14 14:03:12  阅读:227  来源: 互联网

标签:__ .__ setattr Dict2Obj self dict def


 

 

 

class B:
    def __setattr__(self,key,value):
        pass
        raise NotImplementedError

类方法__setattr__覆盖父类方法后,如果为pass, raise NotImplementedError之类的,则实例不能设置任何属性

pass不会报错,raise NotImplementedError会抛异常

但是类可以继续增加属性,__setattr__为实例方法

但是实例的__dict__为一个空dict,这是__new__方法创建实例的时候已经创建好的,在__setattr__之前,

所以可以通过直接操作实例的__dict__来变相添加属性

 

 

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__依然可以增加,不提倡



标签:__,.__,setattr,Dict2Obj,self,dict,def
来源: https://www.cnblogs.com/dissipate/p/13973063.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有