python进阶-面向对象编程四:包装授权和自定制列表某些方法
包装和授权
# 包装和授权 # 包装的过程:一个类型通常是对已存在的类型的一些定制, # 这种做法可以新建,修改或删除原有产品的功能,其它的则保持原样。 # 授权是包装的一个特性。 # 授权的过程:所有更新的功能都是由新类的某部分来处理, # 但已存在的功能就授权给对象的默认属性。 # 授权的过程:所有更新的功能都是由新类的某部分来处理, # 但已存在的功能就授权给对象的默认属性。 # # 应用: 定制自己的数据类型: # 1.继承的方式 # 2.授权的方式
举个例子
# 举个例子 import time class FileHandle: def __init__(self,filename,mode='r',encoding='utf-8'): self.file=open(filename,mode,encoding=encoding) def write(self,line): t=time.strftime('%Y-%m-%d %T') self.file.write('%s %s' %(t,line)) def __getattr__(self, item): return getattr(self.file,item) f1=FileHandle('b.txt','w+') f1.write('你好啊') f1.seek(0) print(f1.read()) f1.close()
# 练习一:重写自定制列表的append和insert方法
class List(list): def append(self,object:str): if not isinstance(object,int): raise TypeError("must int") super().append(object) def insert(self, index: int, object): if not isinstance(object,int): raise TypeError("must int") super().insert(index,object) l=List([1,2,3]) print(l) # [1, 2, 3] l.append(4) #会调用类本身的append方法 print(l) # [1, 2, 3, 4] # l.append("hello") 我们重写了append方法,要求他只能接受int # raise TypeError("must int") l.insert(0,-1) #第一个0是索引,必需是int,第二个规定是int # l.insert(0,"hello") #报错,因为我们重写了增加和插入方法,非int类型插入报错,必须是int类型 print(l) # [-1, 1, 2, 3, 4]
# 练习二:根据需求自定制列表
# 练习: # 定制自己的列表类型,要求定制的自己的__init__方法, # 定制自己的append:只能向列表加入字符串类型的值 # 定制显示列表中间那个值的属性(提示:property) # 其余方法都使用list默认的,比如insert()可以插入数字(提示:__getattr__加反射) # 练习二 class List: def __init__(self, seq): self.seq = seq def append(self, p_object): ' 派生自己的append加上类型检查,覆盖原有的append' if not isinstance(p_object, str): raise TypeError('must be str') else: self.seq.append(p_object) @property def mid(self): '新增自己的方法' index = len(self.seq) // 2 return self.seq[index] # 没有该属性时候的处理方式,自动调用__getattr__,自动调用原列表insert方法 # 注意此处,因为是对象的属性是self,但是getattr里面的是自己定制的init,self.seq,否则造成递归 def __getattr__(self, item): print("传入__getattr__:",self.seq,item) return getattr(self.seq, item) # 造成递归 # def __getattr__(self, item): # return getattr(self,item) def __str__(self): return str(self.seq) x = ['h', 'e', 'l', 'l'] l = List(x) print(l) # ['h', 'e', 'l', 'l'] # 实现取特定数据类型的添加 l.append('o') print(l) # ['h', 'e', 'l', 'l', 'o'] # 实现取中间值方法 print(l.mid) # l # 其余方法用默认的,比如insert l.insert(0, -123) print(l) # 传入__getattr__: ['h', 'e', 'l', 'l', 'o'] insert 列表序列和方法 # [-123, 'h', 'e', 'l', 'l', 'o']
练习三:权限与列表
# 练习三 class List: def __init__(self, seq, permission=False): self.seq = seq self.permission = permission def clear(self): if not self.permission: raise PermissionError('not allow the operation') self.seq.clear() def __setattr__(self, key, value): if not self.permission: raise PermissionError('not allow the operation') else: self.__dict__[key] = value def __setattr__(self, key, value): if not isinstance(value, str): raise TypeError("must be str") self.__dict__[key] = value def __delattr__(self, item): self.__dict__.pop() def __str__(self): return str(self.seq) l = List([1, 2, 3]) # l.clear() #此时没有权限,抛出异常 l.permission = True print(l) l.clear() print(l) # 基于授权,获得insert方法 l.insert(0, -123) print(l)