这是类相关的
没有这个属性抛出异常
getattr跟类调用无关,跟实例调用是可以的,实例调用属性的时候,属性 存在,首先找自己树立的属性,没有就找自己类的,再往上找祖先
getattr并没有改变属性搜索顺序,当你搜索一个属性没有找到的时候,如果没有getattr就会抛出异常
如果有getattr,发现找不到属性需要报attributeerror,就会来找getattr,返回none了
这样就返回abc了,这个方法的返回值就称为你这个属性的返回值
这个能做的事情很多,找不到竟然可以拦住做最后的改动
这个实例找不到属性,然后进入getattr方法
首先按照属性搜索方式,找自个字典,类字典,祖先类字典,找不到getattr魔术方法,但是只影响实例
getattr(a,‘c’)等价于a.c
setattr
前三个需要记住
走一遍看看
A。x找不到
找不到x就是attributeerror
不注释的时候,反而什么都没了
执行20行的时候,初始化完成了,要做实例属性的赋值
赋值的时候,settattr拦住,self。x=x,这里只是打印了一下,什么都没做,所以字典是空的,报出attributeerror
这样就成了,字典的key操作跟self没有关系
这部分是访问属性
setattr的执行时机是,只要使用self.x=xx或者setattr(self,‘y’,y),一定会调用setattr
可以自己搞一个字典存
字典取到了就不是self,下面两个方法就管不到了
getattr是整个属性搜索找不到了,实例搜索找不到,定义了getattr就会执行,执行什么操作就要看你写什么了
setattr但凡是属性赋值都能影响,所以执行时机是跟getattr不一样的
可以自己定义属性字典往里面塞东西
delattr
del这个叫析构方法
delattr删除属性
这是删除属性字典的kv对,不受delattr控制
getattribute
实例化就出现问题了,这里就出现了问题
这是D的来源
访问self.d的时候被getattribute拦住了
int不支持赋值
无条件调用,实现属性访问,对类实例来讲,无条件调用,如果定义了getattr,没有用,因为getattribute更早调用
递归了,raise出了问题给getattr,self,d回到getattribute
大多数情况天用后面的object.__getattribute
交给基类来做
都是加到自己字典里去
到getattribute里去了
如果没有getattribute一定会加到属性的字典里去
对这个访问还需要进入getattribute
有了getattribute整个访问方式就发生了一些变化
只要是实例的属性访问,getattribute,哪怕是dict,self.xx后面都是属性,首先都会调用getattribute方法,阻止了属性的查找,该方法应该返回某个值或者抛出attributeerror异常
找到之后按照道理还需要这样调用,下面该怎么找属性还是要怎么找
找属性都要从getattribute里过,然后甩给基类来处理了
返回1就全是1,原有的属性访问方式就不存在了
在getattribute这一关可以抛出异常(找到getattr),返回固定值,返回每个对应的值、
调用基类的方法按照原有策略去找属性
大部分是找不到会写这个的,除非有特殊需求
属性找不到了找它,是最后一道防线
只要实例赋值都管
只要通过实例来删除都管,哪怕这个属性属于类属性
只要通过实例访问属性,就管
一般后面的比较重要,但是getattribute是第一位
这就是反射,都通运行时,通过实例来访问类型属性信息,也就是反射机制