当我们要用一个类来存储数据库中的一条信息,但是我们不知道这条信息中都有什么数据,这时候我们可以利用按需生成属性的方式来保存未知的信息。
__getattr__
按需生成属性可以通过__getattr__
特殊方法来实现。如果某个类定义了__getattr__
方法,同时系统在该类对象的实例字典中有差找不到待查询的属性,那么系统就会调用这个方法。
1 | class LazyDB(): |
执行结果:
1 | Before {'exist': 5} |
代码中访问了实例的没有的 foo 属性,这会使解释器自动调用上面定义的__getattr__
方法,里面的setattr函数给实例添加了foo属性。
__getattribuate__
__getattribuate__
方法在访问类的属性的时候会自动调用。
__setattr__
__setattr__
函数无论是在类中给属性赋值,还是在实例中给属性赋值,都会被调用。
1 | class LazyDB(): |
执行结果:
1 | add attr:exist |
我们重写这些内置方法时,可以自行在里面添加一些东西,比如提示什么的。
要注意的是,重写__getattribuate__
方法和__setattr__
方法时,需要通过 super() 来完成,否则会陷入无限递归。比如:
1 | class BrokenDictionaryDB(object): |
上面这个代码就会陷入无限递归,因为return self.name
又会调用__getattribute__
方法。
通过super()来完成就可以防止此问题:
1 | class BrokenDictionaryDB(object): |