一直对这个魔法方法不是分的很清楚,后来自己逐个梳理了一下,熟悉了这家族的用法,现在结合dict类,示范一下这几类方法的具体用途和使用场景:
class Person(dict):
def __init__(self, *args, **kwargs):
super(Person, self).__init__(*args, **kwargs)
self.name = "zhangsan"
self.age = 18
def __getattr__(self, key, *args, **kwargs):
print("__getattr__,key:%s" % key)
def __setattr__(self, key, value, *args, **kwargs):
"""实例对象设置属性时,本质上是调用了__setattr__方法"""
print("__setattr__,key:%s, value:%s" % (key, value))
super(Person, self).__setattr__(key, value, *args, **kwargs)
self[key] = value # 调用__setitem__
def __getattribute__(self, key, *args, **kwargs):
"""实例对象.属性 进行这类操作时,本质上是调用__getattribute__方法 """
print("__getattribute__,key:%s" % key)
return super(Person, self).__getattribute__(key, *args, **kwargs) # 既然是获取属性的值,获取的结果肯定是返回的
def __setitem__(self, key, value, *args, **kwargs):
"""对字典对象的键值对赋值,本质上是调用__setitem__方法"""
print("__setitem__,key:%s, value:%s" % (key, value))
super(Person, self).__setitem__(key, value, *args, **kwargs)
# self.__setattr__(key, value, *args, **kwargs)
def __getitem__(self, key, *args, **kwargs):
"""获取字典对象的key对应的值时,本质上是调用对象的___getitem__"""
print("__getitem__,key:%s" % key)
return super(Person, self).__getitem__(key, *args, **kwargs)
person = Person()
jillian = dict() # 普通字典
# 类型区别
print(type(person)) # 打印实例对象的格式可以看出来,继承于dict类的子类不再是dict类型,而是基于__main__的子类,但是继承于dict类
print(type(jillian))
# get
print(person.name) # 实例对象.属性 进行这类操作时,本质上是调用__getattribute__方法,里面已经定义了name属性,所以这里可以打印属性,没毛病
print(person['name']) # 获取一个字典对象的key对应的值时,本质上是调用对象的___getitem__
# set
person.name = "lisi"
print(person.name)
print(person['name'])
person['age'] = 10
print(person.age)
print(person['age'])
执行结果为:
__setattr__,key:name, value:zhangsan
__setitem__,key:name, value:zhangsan
__setattr__,key:age, value:18
__setitem__,key:age, value:18
<class '__main__.Person'>
<class 'dict'>
__getattribute__,key:name
zhangsan
__getitem__,key:name
zhangsan
__setattr__,key:name, value:lisi
__setitem__,key:name, value:lisi
__getattribute__,key:name
lisi
__getitem__,key:name
lisi
__setitem__,key:age, value:10
__getattribute__,key:age
18
__getitem__,key:age
10