1,__getattribute__
当实例调用某个属性或方法时,首先会调用__getattrbute__,也就是相当于默认调用该方法(隐含默认调用,无论何种情况,均会调用此方法).
class Test:
def __getattr__(self, name):
print('__getattr__')
def __getattribute__(self, name):
print('__getattribute__')
object.__getattribute__(self,name) #如果没有这一步,那么就不会调用__getattr__方法
def __setattr__(self, name, value):
print('__setattr__')
def __delattr__(self, name):
print('__delattr__')
>>> t=Test()
>>> t.x
__getattribute__
__getattr__
步骤:
实例t.x时,默认调用__getattribute__方法,
1,调用该方法的时候,首先会从实例的__dict__方法中找该方法
2,如果1没找到,那么就会从该实例的父类的__dict__找该方法,
3,如果前面都没找到,那么就会执行__getattr__,然后做进一步的操作
PS(重点):
开始走__getattribute__方法时,如果没有调用object.__getattribute__(self,name),那么操作只会在__getattribute__方法内部执行完毕就停了,
但是如果调用的object的__getattribute__方法,那么没有调用__getattr__就会报错
2,__getattr__
当实例对象访问不存在的属性时调用
以上面的例子为例,只要是不存在的属性,都会访问__getattr__
3,__setattr__
设置实例对象的一个新的属性时调用
class Test:
def __init__(self,name):
print('start init')
self.name = name
print('end init') def __setattr__(self, name, value):
print('__setattr__') t = Text('forjie')
==>打印步骤
start init
__setattr__
end init
为什么?
当类开始实例化时,走init,但是当执行self.name = name,就会调用__setattr__方法,
另外说一下报错的情况
class Test: def __init__(self): self.count = 0 def __setattr__(self, name, value): print('__setattr__') self.count += 1 >>> t=Test() __setattr__ Traceback (most recent call last): File "<pyshell#364>", line 1, in <module> t=Test() File "<pyshell#363>", line 3, in __init__ self.count = 0 File "<pyshell#363>", line 6, in __setattr__ self.count += 1 AttributeError: 'Test' object has no attribute 'count'
为什么?
1,当走init时,self.count = 0会调用__setattr__,但是因为这个时候没有这个属性,所以会报错
防止报错
def __setattr__(self, name, value): print('__setattr__') self.count += 1
return object.__setattr__(self,name,value+1)
或者
return super().__setattr__(name,value)
这里要注意,首先是如果是object有self,而super的话是没有self的.