上节课复习
设置自己的数据类型
#基于继承来定制自己的数据类型 class List(list): #继承list所有的属性,也可以派生出自己新的,比如append和mid def append(self, p_object): ' 派生自己的append:加上类型检查' if not isinstance(p_object,int): raise TypeError('must be int') super().append(p_object) # @property def mid(self): '新增自己的属性' index=len(self)//2 return self[index] # # l=List([1,2,3]) # # print(l.mid) #基于授权来定制自己的数据类型: # class Open: # def __init__(self,filepath,mode,encode='utf-8'): # self.f=open(filepath,mode=mode,encoding=encode) # self.filepath=filepath # self.mode=mode # self.encoding=encode # # def write(self,line): # print('write') # self.f.write(line) # # def __getattr__(self, item): 找不到就到getattr里面找 # return getattr(self.f,item) # # # # f=Open('a.txt','w') # # f.write('123123123123123 ') # # print(f.seek) # # f.close() # # # # f.write('111111 ') # # # # f=open('b.txt','w') # f.write('bbbbbb ') # f.close() # print(f) # class Foo: # def test(self): # pass # # print(getattr(Foo,'test')) # # obj=Foo() # print(getattr(obj,'test')) class List: def __init__(self,x): self.seq=list(x) def append(self,value): if not isinstance(value,str): raise TypeError('must be str') self.seq.append(value) @property def mid(self): index=len(self.seq)//2 return self.seq[index] def __getattr__(self, item): return getattr(self.seq,item) def __str__(self): return str(self.seq) l=List([1,2,3]) l.append('1') print(l.mid) l.insert(0,123123123123123123123123123) # print(l.seq) print(l) obj.name='egon' del obj.name
__solt__
加完这个之后对像不会再建自己的名称空间了,只能设我__solts下的值,不用产生dict也能加名称空间, 节省内存空间,可以限制你的属性 用于一个类可能产生好几w个属性,但是是相同的,然后节省空间 # class People: # x=1 # def __init__(self,name): # self.name=name # def run(self): # pass # # # print(People.__dict__) # # p=People('alex') # print(p.__dict__) class People: __slots__=['x','y','z'] p=People() print(People.__dict__) p.x=1 p.y=2 p.z=3 print(p.x,p.y,p.z) # print(p.__dict__) p1=People() p1.x=10 p1.y=20 p1.z=30 print(p1.x,p1.y,p1.z) print(p1.__dict__)
item系列
#把对象操作属性模拟成字典的格式 class Foo: def __init__(self,name): self.name=name def __setattr__(self, key, value): print('setattr===>') 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): self.__dict__.pop(key) # self.__dict__.pop(key) # def __delattr__(self, item): # print('del obj.key时,我执行') # self.__dict__.pop(item) f=Foo('egon') f.name='egonlin' f['name']='egonlinhai' # print(f.name) # f.name='egonlin' # f['age']=18 # print(f.__dict__) # # del f['age'] #del f.age # print(f.__dict__) # print(f['name'])
实现迭代器协议
# from collections import Iterable,Iterator # class Foo: # def __init__(self,start): # self.start=start # # def __iter__(self): # return self # # def __next__(self): # return 'aSB' # # # f=Foo(0) # f.__iter__() # f.__next__() # print(isinstance(f,Iterable)) # print(isinstance(f,Iterator)) # # print(next(f)) #f.__next__() # print(next(f)) #f.__next__() # print(next(f)) #f.__next__() # for i in f: # res=f.__iter__() #next(res) # print(i) # from collections import Iterable,Iterator # class Foo: # def __init__(self,start): # self.start=start # # def __iter__(self): # return self # # def __next__(self): # if self.start > 10: # raise StopIteration # n=self.start # self.start+=1 # return n # # f=Foo(0) # print(next(f)) # print(next(f)) # print(next(f)) # print(next(f)) # print(next(f)) # print(next(f)) # print(next(f)) # print(next(f)) # print(next(f)) # print(next(f)) # print(next(f)) # print(next(f)) # # for i in f: # print('====>',i) # class Range: # '123' # def __init__(self,start,end): # self.start=start # self.end=end # # def __iter__(self): # return self # # def __next__(self): # if self.start == self.end: # raise StopIteration # n=self.start # self.start+=1 # return n # # for i in Range(0,3): # print(i) # # # # print(Range.__doc__) class Foo: '我是描述信息' pass class Bar(Foo): pass print(Bar.__doc__) #该属性无法继承给子类 b=Bar() print(b.__class__) print(b.__module__) print(Foo.__module__) print(Foo.__class__) #?
析构函数
import time class Open: def __init__(self,filepath,mode='r',encode='utf-8'): self.f=open(filepath,mode=mode,encoding=encode) def write(self): pass def __getattr__(self, item): return getattr(self.f,item) def __del__(self): print('----->del') self.f.close() 通常就用来写上,关闭的操作 f=Open('a.txt','w') f1=f del f print('=========>')
__enter__方法,上下文管理协议
# with open('a.txt','r') as f: # print('--=---->') # print(f.read()) # with open('a.txt', 'r'): # print('--=---->') # class Foo: def __enter__(self): print('=======================》enter') return 111111111111111 def __exit__(self, exc_type, exc_val, exc_tb): print('exit') print('exc_type',exc_type) print('exc_val',exc_val) print('exc_tb',exc_tb) return True # with Foo(): #res=Foo().__enter__() # pass with执行先去触发__enter__方法,然后,再去执行with里面的语句,最后去执行__exit方法, 如果有主动异常,你没处理,接下来的都不执行,如果有处理true什么的,就会继续执行 with Foo() as obj: #res=Foo().__enter__() #obj=res print('with foo的自代码块',obj) raise NameError('名字没有定义') print('************************************') print('1111111111111111111111111111111111111111')
# import time # class Open: # def __init__(self,filepath,mode='r',encode='utf-8'): # self.f=open(filepath,mode=mode,encoding=encode) # # def write(self,line): # self.f.write(line) # # # def __getattr__(self, item): # return getattr(self.f,item) # # def __del__(self): # print('----->del') # self.f.close() # # def __enter__(self): # return self.f # def __exit__(self, exc_type, exc_val, exc_tb): # self.f.close() # # # with Open('egon.txt','w') as f: # f.write('egontest ') # f.write('egontest ') # f.write('egontest ') # f.write('egontest ') # f.write('egontest ')
call方法
class People: def __init__(self,name): self.name=name # def __call__(self, *args, **kwargs): print('call') # p=People('egon') print(callable(People)) print(callable(p)) callable可调用对象就是加()能运行的那种 p() 用法对象加()会去找call方法,原来是不能加()的
元类
模拟创建类的过程 class People: def __init__(self,name): self.name=name p=People('egon') # print(type(p)) # # print(type(People)) #typer--->类------>对象 class Foo: x=1 def run(self): pass print(type(Foo)) #type成为元类,是所有类的类,利用type模拟class关键字的创建类的过程 类的三要素,名称空间,字典,继承 def run(self): print('%s is runing' %self.name) class_name='Bar' bases=(object,) class_dic={ 'x':1, 'run':run } Bar=type(class_name,bases,class_dic) print(Bar) print(type(Bar))
模拟创建类的过程 class People: def __init__(self,name): self.name=name p=People('egon') # print(type(p)) # # print(type(People)) #typer--->类------>对象 class Foo: x=1 def run(self): pass print(type(Foo)) #type成为元类,是所有类的类,利用type模拟class关键字的创建类的过程 类的三要素,名称空间,字典,继承 def run(self): print('%s is runing' %self.name) class_name='Bar' bases=(object,) class_dic={ 'x':1, 'run':run } Bar=type(class_name,bases,class_dic) print(Bar) print(type(Bar))
自定元类
元类就是类的类,可以控制类的形为,如下面,你用自定认的元类,创建类的时候,必须加上注释 元类不要花太多精力 type是所有类的元类, # class Foo(metaclass=type):设置自己的元类 # x=1 # def run(self): # print('running') # # # # type('Foo',(object,),{'x':1,'run':run}) # class Mymeta(type): # def __init__(self,class_name,class_bases,class_dic): # # print(self) # # print(class_name) # # print(class_bases) # # print(class_dic) # for key in class_dic: # if not callable(class_dic[key]):continue 所有函数都是可调用的有callable属性 # if not class_dic[key].__doc__: # raise TypeError('小子,你没写注释,赶紧去写') # # # type.__init__(self,class_name,class_bases,class_dic) # class Foo(metaclass=Mymeta): # x=1 # def run(self): # 'run function' # print('running') # Foo=Mymeta('Foo',(object,),{'x':1,'run':run}) # print(Foo.__dict__) class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): pass def __call__(self, *args, **kwargs): # print(self) obj=self.__new__(self) self.__init__(obj,*args,**kwargs) #obj.name='egon' return obj class Foo(metaclass=Mymeta): x=1 def __init__(self,name): self.name=name #obj.name='egon' def run(self): 'run function' print('running') # print(Foo.__dict__) f=Foo('egon') print(f) print(f.name)