__setattr__,__getattr__,__getattribute__

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的.

 

猜你喜欢

转载自www.cnblogs.com/52forjie/p/10130973.html