十五. 面向对象二次加工标准类型(包装)授权

一.包装


# 二次加工标准类型(包装)
# :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("哈哈哈哈哈哈\n")
# aa.write("啦啦啦啦啦啊\n")

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]

 

posted @ 2019-06-24 21:05  supreme9999  阅读(221)  评论(0编辑  收藏  举报