Python 基础 四 面向对象杂谈
一、isinstance(obj,cls) 与issubcalss(sub,super)
isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo: pass f1=Foo() print(isinstance(f1,Foo)) #True issubclass(sub, super)检查sub类是否是 super 类的派生类 class Foo: pass class Xoo(Foo): pass print(issubclass(Xoo,Foo)) #True
二、__getattribute__
在介绍__getattribute__之前是否还记得之前学过一个叫__getattr__的方法,这两者之间是否存在某种关系呢?实际上呢,还是有关系的,是个什么情况呢,就是大哥和小弟的关系,有大哥在的时候大哥上,大哥不在小弟上,或者大哥不想干了,让给了小弟,那你小弟就必须上了是吧。
先看一下__getattr__的例子:
class Foo: def __init__(self,x): self.x=x def __getattr__(self, item): print('执行的是我') # return self.__dict__[item] f1=Foo(10) print(f1.x) #d当访问的属性存在的时候是不会触发__getattr__ #f1.xxxxxx #不存在的属性访问,触发__getattr__,若自己没有重写此方法时,就会触发系统默认的此方法,若重写了就会按你自己写的东西执行
好了,再看一下两个都存在的触发方式及结果:
class Foo: def __init__(self,x): self.x=x def __getattr__(self, item): print('执行的是getattr') # return self.__dict__[item] def __getattribute__(self, item): print('执行的是getattribute') raise AttributeError('抛出异常了') # raise TabError('xxxxxx') f1=Foo(10) #f1.x f1.xxxxxx #不存在的属性访问,触发__getattr__,若有__getattribute__就先触发此方法(不管属性是否存在),若后面有raise方法抛出异常的时候,就会再次交给__getattr__处理
三、item系列
看到这里是否还记得之前说过一个系列叫做:attr,这两者又是什么关系?我们先看看item系列
class Foo: def __getitem__(self, item): print('getitem',item) #return self.__dict__[item] def __setitem__(self, key, value): print('setitem') self.__dict__[key]=value def __delitem__(self, key): print('delitem') self.__dict__.pop(key) f1=Foo() #print(f1.__dict__) #对象f1的属性字典是空的————》{} #f1.name='egon'#---->setattr-------->f1.__dict__['name']='egon' #print(f1.__dict__) #{'name': 'egon'} f1['name']='egon'#--->setitem--------->f1.__dict__['name']='egon' f1['age']=18 #会触发 内部的__setitem__方法 # print('===>',f1.__dict__) # ===> {}查看属性字典却没有添加进去,只是触发了内部的__setitem__方法,若要添加上,就必须对底层进行操作: self.__dict__[key]=value # 这样就把属性字典添加上了 ===> {'name': 'egon', 'age': 18} del f1.name # 删除属性值 print(f1.__dict__) # {'age': 18} # # print(f1.age) del f1['name'] #触发__delitem__,若要真实的删除属性字典中的值就必须对底层进行操作: self.__dict__.pop(key) #print(f1.__dict__)