一.包装
# 二次加工标准类型(包装)
# :python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制
# 我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均可以通过下面的方式进行二次加工)
# 意思就是对已经存中的一个类型或者对象python自动的 进行第二次修改或者自定义自己的属性
自己定义的方法和父类同名了 用自己定义的方法
class Da(list): #继承list所有的属性,也可以派生出自己新的,比如append和ser
def append(self,y):
if type(y)is str:
# self.append(y) # 这样是不得行的白痴
# super().append(y) # super去调用的父类方法继承父类append
list.append(self,y)
else:
print("你输入的有问题")
@property
def ser(self):
inde=len(self)//2
return self[inde]
aa=Da("helloword")
print("**************************************************")
aa.append("ww")
print(aa)
print(aa.ser)
aa.append("1111")
print(aa)
# ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'd', 'ww']
# w
# ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'd', 'ww', '1111']
def __init__(self,item,tag=False): super().__init__(item) self.tag=tag def append(self, p_object): if not isinstance(p_object,str): raise TypeError super().append(p_object) def clear(self): if not self.tag: raise PermissionError super().clear() l=List([1,2,3],False) print(l) print(l.tag) l.append('saf') print(l) # [1, 2, 3] # False # [1, 2, 3, 'saf']
授权
授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。 其它的则保持原样。授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。 实现授权的关键点就是覆盖__getattr__方法 文件操作有什么就继承什么 就比如说 open()方法 class Open(object): def __init__(self,pathname,mod="r",encoding="utf-8"): self.file=open(pathname,mod,encoding=encoding) self.mod=mod self.encoding=encoding def write(self,line): self.file.write(line) # __getattr__ 对象调用一个没得属性才会触发 def __getattr__(self, item): print(type(item),item) return getattr(self.file,item) aa=Open("aa","r") print(aa.__dict__) print(aa.file) print(aa.read()) # aa.write("哈哈哈哈哈哈 ") # aa.write("啦啦啦啦啦啊 ") print("*******************************************************************888") aa=open("aa","r+",encoding="utf-8") cc=getattr(aa,"read") print(cc) # {'file': <_io.TextIOWrapper name='aa' mode='r' encoding='utf-8'>, 'mod': 'r', 'encoding': 'utf-8'} # <_io.TextIOWrapper name='aa' mode='r' encoding='utf-8'> # <class 'str'> read # 1111111111111111111 # *******************************************************************888 # <built-in metho
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()
#练习一 class List: def __init__(self,seq): self.seq=seq def append(self, p_object): ' 派生自己的append加上类型检查,覆盖原有的append' if not isinstance(p_object,int): raise TypeError('must be int') self.seq.append(p_object) @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]) print(l) l.append(4) print(l) # l.append('3333333') #报错,必须为int类型 print(l.mid)
基于授权,获得insert方法 会触发__getattr__方法 因为实例化中没有这个方法 复合__getattr__属性
l.insert(0,-123)
print(l)
# [1, 2, 3]
# [1, 2, 3, 4]
# 3
# [-123, 1, 2, 3, 4]