类的其他方法
1、isinstance(obj,cls)
判断对象是否是类产生的,返回TRUE或FALSE
class Foo: pass f1=Foo() print(isinstance(f1,Foo))#True
2、issubclass(cls,super)
判断子类是否是父类产生的,返回TRUE或FALSE
class sell: pass class Foo(sell): pass f2=Foo() print(issubclass(Foo,sell))#True
3、__getattribute__(self,item)
只要对象调用属性,不管这个属性存不存在都会触发__getattritube__的运行执行它内部的代码
使用raise功能可以做异常处理,raise AttributeError()可以让__getattr__接管运行
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Foo: def __init__(self,name): self.name=name def __getattr__(self, item): print('执行=======》getattr',item) def __getattribute__(self, item): print('执行++++++++》getattrrbute',item) raise AttributeError('已终止') f1=Foo('飞乐') # print(f1.__dict__)#执行++++++++》getattrrbute __dict__ f1.name #执行++++++++》getattrrbute name #执行=======》getattr name f1.sjdlkf #执行++++++++》getattrrbute sjdlkf #执行=======》getattr sjdlkf
4、get,set,del,的item*方法
中括号[]操作方式和item相关,点的操作方式和attr相关
item方法和attr方法类似区别在于一个用点找属性,一个用[]中括号找属性
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Foo: def __init__(self,name,age): self.name=name self.age=age def __getitem__(self, item): print('在执行----》getitem') def __setitem__(self, key, value): print('在执行---->setattr') self.__dict__[key]=value def __delitem__(self, key): print('正在执行---->delitem') f1=Foo('飞乐',18) print(f1.__dict__)#{'name': '飞乐', 'age': 18} f1.sex='male'#没有触发setitem print(f1.__dict__)#{'name': '飞乐', 'age': 18, 'sex': 'male'} f1['age']=16#在执行---->setattr print(f1.__dict__)#{'name': '飞乐', 'age': 16, 'sex': 'male'} f1.age#没有触发getitem f1['age']#在执行----》getitem f1['sdjfkl']#在执行----》getitem
5、str控制输出
改变对象的字符串显示,控制输出内容
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Foo: def __init__(self,name,age): self.name=name self.age=age def __str__(self): return '名字是:%s ,年龄是:%s'%(self.name,self.age) f1=Foo('飞乐',18) print(f1)#名字是:飞乐 ,年龄是:18 #实际调用方式:str(f1)------>f1.__str__() print(str(f1))#名字是:飞乐 ,年龄是:18 print(f1.__str__())#名字是:飞乐 ,年龄是:18
6、repr控制输出
str和repr都是控制输出功能,区别repr是在解释器中使用的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Foo: def __init__(self,name,age): self.name=name self.age=age # def __str__(self): # return '这是str' def __repr__(self): return '名字是:%s 年龄是:%s'%(self.name,self.age) f1=Foo('飞乐',18) print(f1)#这是str #实际运行:repr(f1)------>f1.__repr__() #如果没有str方法就会去找repr作为替代品 print(f1)#名字是:飞乐 年龄是:18
7、__format__(self,format_spec)控制输出格式
利用format方法格式化输出
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #平时使用的format格式化方法 2 a='{0}{0}{0}'.format('飞乐') 3 print(a)#飞乐飞乐飞乐 4 5 #面向对象中使用(这个方式太low) 6 class Date: 7 def __init__(self,year,month,day): 8 self.year=year 9 self.month=month 10 self.day=day 11 d1=Date(2018,10,1) 12 x='{0.year}{0.month}{0.day}'.format(d1) 13 y='{0.year}:{0.month}:{0.day}'.format(d1) 14 z='{0.year}-{0.month}-{0.day}'.format(d1) 15 print(x)#2018101 16 print(y)#2018:10:1 17 print(z)#2018-10-1 18 19 20 #====================>low的升级版 21 22 data_dict={ 23 'ymd':'{0.year}{0.month}{0.day}', 24 'y:m:d':'{0.year}:{0.month}:{0.day}', 25 'y-m-d':'{0.year}-{0.month}-{0.day}', 26 } 27 28 class Date: 29 def __init__(self,year,month,day): 30 self.year=year 31 self.month=month 32 self.day=day 33 def __format__(self, format_spec): 34 #format执行必须返回一个字符串类型, 35 #format_spec是什么内容就打印什么内容 36 print('执行———》format',format_spec) 37 #此处加个判断:当输入不规则格式时,提供默认格式 38 if not format_spec or not format_spec in data_dict: 39 format_spec='y-m-d' 40 fm=data_dict[format_spec] 41 return fm.format(self) 42 43 d1=Date('2018','10','1') 44 print(d1.__dict__)#{'year': '2018', 'month': '10', 'day': '1'} 45 #format(d1)=====>d1.__format__() 46 print(format(d1,'ymd'))#执行———》format ymd 2018101 47 print(format(d1,'y:m:d'))#执行———》format y:m:d 2018:10:1 48 print(format(d1,'y-m-d'))#执行———》format y-m-d 2018-10-1 49 print(format(d1,'sss'))#执行———》format sss 2018-10-1
8、__slots__是什么?
它是一个类变量,变量值可以是列表,元组,或者可迭代对象,也可以是一个字符串,利用slots可以省内存(怎么省的我也不知道^_^)
它如果定义在类中,产生的实例不再有__dict__方法
class Foo: #此处列表里有多少属性只能设置多少属性 __slots__ = ['name','age'] f1=Foo() # print(f1.__dict__)#没有__dict__方法 AttributeError: 'Foo' object has no attribute '__dict__' f1.name='飞乐'#----->setattr------>f1.__dict__['name']='飞乐' print(f1.name)#飞乐 print(f1.__slots__)#['name', 'age']
9、__doc__()
doc属性是无法被继承的
class Foo: '我是描述信息' pass class Bar(Foo): pass print(Foo.__doc__)#我是描述信息 print(Bar.__doc__)#None
10、__del__(self)析构方法
当对象在内存中被释放时,自动触发执行
class Foo: def __init__(self,name): self.name=name def __del__(self): print('我执行了') f1=Foo('飞乐') # del f1 #我执行了 print('------------------------>')#------------------------>
11、__call__(self,*arg,**kwargs)
对象后面加括号,触发执行
class Foo: def __call__(self, *args, **kwargs): print('实例执行了 obj()') f1=Foo()#触发了call方法 f1()#Foo下面的__call__实例执行了 obj() Foo()#xxx下的__call
12、迭代器协议
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class Foo: 2 def __init__(self,n): 3 self.n=n 4 #加iter方法成为可迭代对象 5 def __iter__(self): 6 return self 7 8 def __next__(self): 9 if self.n==100: 10 raise StopIteration('终止了') 11 self.n+=1 12 return self.n 13 14 # l=list('hello') 15 # for i in l: 16 # print(i) 17 18 f1=Foo(10) 19 print(f1.__next__()) 20 print(next(f1)) 21 for i in f1: #obj=f1.__iter__() ====== iter(f1) 22 print(i) #obj.__next__()
2、迭代器协议实现斐波那契数列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class Fib: 2 def __init__(self): 3 self._a=1 4 self._b=1 5 def __iter__(self): 6 return self 7 def __next__(self): 8 if self._a>100: 9 raise StopIteration('已终止') 10 self._a,self._b=self._b,self._a + self._b 11 return self._a 12 13 f1=Fib() 14 print(next(f1)) 15 print(next(f1)) 16 print(next(f1)) 17 print('===================') 18 for i in f1: 19 print(i)
13、描述符
数据描述符分两种一种是数据描述符:至少实现了__get__()和__set__()
第二种是非数据描述符:没有实现__set__()
描述符优先级排序:类属性>数据描述符>实例属性>非数据描述符>找不到,找不到的属性触发__getattr__()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class Foo: 2 def __get__(self, instance, owner): 3 print('======>get') 4 def __set__(self, instance, value): 5 print('=======>set') 6 instance.__dict__['x']=value #f1.__dict__ 7 def __delete__(self, instance): 8 print('=======>del') 9 10 class Bar: 11 x=Foo()#在实例化时x会被Foo代理 12 def __init__(self,n): 13 self.x=n#b1.x=10 14 15 b1=Bar(10)#初始化时设置属性会被Foo里面的set代理打印 =======>set 16 print(b1.__dict__)#{'x': 10} 17 b1.x=11111#被代理打印=======>set 18 print(b1.__dict__)#{'x': 11111} 19 20 b1.y=22222222222 21 print(b1.__dict__)#{'x': 11111, 'y': 22222222222}