目录
一、问题来源
发现ml_collections的ConfigDict实例对象,可以通过对象名.属性名的方法添加新的属性,也能够通过对象名[属性名]的方式来添加新的元素。感到很好奇,因为ConfigDict看上去就是一个普通的类。
二、思考
查阅资料发现:其实通过.进行添加新的属性的方法是通过__setattr__魔法方法;而通过[]添加新的属性是通过__setitem__魔法方法。
三、实现代码
class A:
def __init__(self, data):
# 这个赋值方式,是通过__setattr__魔法方法,把dic属性添加到__dict__字典中
# 所以__setattr__想要对dic中添加key-value要先把它加入__dict__
self.dic = data
def __setattr__(self, key, value):
if 'dic' not in self.__dict__:
self.__dict__['dic'] = {}
else:
self.dic.update({key: value})
# 这就是错误的方式,因为到__setattr__方法里面,是还没有dic这个属性的
# self.dic.update({key,value})
def __setitem__(self, key, value):
self.dic.update({key:value})
if __name__=="__main__":
a = A({'age':18})
# [] 添加属性是使用__setitem__方法
a['birthday'] = '2021-10-1'
# 下面两个添加属性是使用__setattr__方法
a.address = '北京'
a.name = "张三"
print(a.dic)
// 输出
{'birthday': '2021-10-1', 'address': '北京', 'name': '张三'}