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)

  

 

posted @ 2017-09-13 19:58  Adamanter  阅读(262)  评论(0)    收藏  举报