zoukankan      html  css  js  c++  java
  • 继承方式完成包装

    包装:python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均可以通过下面的方式进行二次加工)

    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,4])
    print(l)
    l.append(5)
    print(l)
    # l.append('1111111') #报错,必须为int类型
    
    print(l.mid)
    
    #其余的方法都继承list的
    l.insert(0,-123)
    print(l)
    l.clear()
    print(l)
    
    二次加工标准类型(基于继承实现)
    class List(list):
        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)
    
    # l.clear() #异常
    
    l.tag=True
    l.clear()
    
    练习(clear加权限限制)

    授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

    实现授权的关键点就是覆盖__getattr__方法

    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()
    
     授权示范一
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    #我们来加上b模式支持
    import time
    class FileHandle:
        def __init__(self,filename,mode='r',encoding='utf-8'):
            if 'b' in mode:
                self.file=open(filename,mode)
            else:
                self.file=open(filename,mode,encoding=encoding)
            self.filename=filename
            self.mode=mode
            self.encoding=encoding
    
        def write(self,line):
            if 'b' in self.mode:
                if not isinstance(line,bytes):
                    raise TypeError('must be bytes')
            self.file.write(line)
    
        def __getattr__(self, item):
            return getattr(self.file,item)
    
        def __str__(self):
            if 'b' in self.mode:
                res="<_io.BufferedReader name='%s'>" %self.filename
            else:
                res="<_io.TextIOWrapper name='%s' mode='%s' encoding='%s'>" %(self.filename,self.mode,self.encoding)
            return res
    f1=FileHandle('b.txt','wb')
    # f1.write('你好啊啊啊啊啊') #自定制的write,不用在进行encode转成二进制去写了,简单,大气
    f1.write('你好啊'.encode('utf-8'))
    print(f1)
    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方法
    l.insert(0,-123)
    print(l)
    
    
    
    
    
    #练习二
    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 __getattr__(self, item):
            return getattr(self.seq,item)
    
        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)
    
    练习题(授权)

    https://www.cnblogs.com/linhaifeng/articles/6204014.html#_label2

    1

  • 相关阅读:
    es5预览本地文件、es6练习代码演示案例
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 836 矩形重叠(暴力)
    Subversion under Linux [Reprint]
    Subversion how[Reprint]
  • 原文地址:https://www.cnblogs.com/Manuel/p/12852506.html
Copyright © 2011-2022 走看看