类的其他方法
1、isinstance(obj,cls)
判断对象是否是类产生的,返回TRUE或FALSE
class Foo: passf1=Foo()print(isinstance(f1,Foo))#True
2、issubclass(cls,super)
判断子类是否是父类产生的,返回TRUE或FALSE
class sell: passclass Foo(sell): passf2=Foo()print(issubclass(Foo,sell))#True
3、__getattribute__(self,item)
只要对象调用属性,不管这个属性存不存在都会触发__getattritube__的运行执行它内部的代码
使用raise功能可以做异常处理,raise AttributeError()可以让__getattr__接管运行
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 namef1.sjdlkf#执行++++++++》getattrrbute sjdlkf#执行=======》getattr sjdlkf
4、get,set,del,的item*方法
中括号[]操作方式和item相关,点的操作方式和attr相关
item方法和attr方法类似区别在于一个用点找属性,一个用[]中括号找属性
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'#没有触发setitemprint(f1.__dict__)#{'name': '飞乐', 'age': 18, 'sex': 'male'}f1['age']=16#在执行---->setattrprint(f1.__dict__)#{'name': '飞乐', 'age': 16, 'sex': 'male'}f1.age#没有触发getitemf1['age']#在执行----》getitemf1['sdjfkl']#在执行----》getitem
5、str控制输出
改变对象的字符串显示,控制输出内容
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))#名字是:飞乐 ,年龄是:18print(f1.__str__())#名字是:飞乐 ,年龄是:18
6、repr控制输出
str和repr都是控制输出功能,区别repr是在解释器中使用的
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方法格式化输出
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=month10 self.day=day11 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)#201810116 print(y)#2018:10:117 print(z)#2018-10-118 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=year31 self.month=month32 self.day=day33 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 201810147 print(format(d1,'y:m:d'))#执行———》format y:m:d 2018:10:148 print(format(d1,'y-m-d'))#执行———》format y-m-d 2018-10-149 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: '我是描述信息' passclass Bar(Foo): passprint(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、迭代器协议
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+=112 return self.n13 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、迭代器协议实现斐波那契数列
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._b11 return self._a12 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__()
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=1014 15 b1=Bar(10)#初始化时设置属性会被Foo里面的set代理打印 =======>set16 print(b1.__dict__)#{'x': 10}17 b1.x=11111#被代理打印=======>set18 print(b1.__dict__)#{'x': 11111}19 20 b1.y=2222222222221 print(b1.__dict__)#{'x': 11111, 'y': 22222222222}