面向对象进阶2:二次加工标准类型(包装)

二次加工标准类型(包装)

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

#基于继承加派生来实现二次加工标准类型
# 派生原有的list类
class List(list):
    def append(self, p_object):      #自定义一个父类中本来就有的append
        if type(p_object) is str:    #规定只能附加一个字符串
            # self.append(p_object)   #self自己调用自己的方法,陷入递归死循环当中
            super().append(p_object)  #用super()更好,等价于list.append(p_object)
            #调用父类中的append()只要不调用自己的就不会递归死循环
        else:
            print(‘只能添加字符串类型‘)

    def show_midlle(self):           #取列表中的中间的那个值
        mid_index=int(len(self)/2)
        return self[mid_index]

l2=list(‘helloworld‘)   #原来系统内置的list
print(l2,type(l2))       #[‘h‘,‘e‘,‘l‘,‘l‘,‘o‘,‘w‘,‘o‘,‘r‘,‘l‘,‘d‘] <class ‘list‘>

l1=List(‘helloworld‘)   #用从list继承过来的自己的List
print(l1,type(l1))        #[‘h‘,‘e‘,‘l‘,‘l‘,‘o‘,‘w‘,‘o‘,‘r‘,‘l‘,‘d‘] <class ‘_main_.List‘>
# l1的类型为当前运行文件下的一个list类
print(l1.show_midlle())     #w
l1.append(1111111111111111111111)   #非字符串本函数功能不允许,加不成功  #参数会传给p_object
l1.append(‘SB‘)   #是字符串,能成功加入
print(l1)

授权:授权是包装的一个特性, 不通过继承来做。还是想要定制一个原有的标准类型。

包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。其它的则保持原样。

授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

实现授权的关键点就是覆盖__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/Josie-chen/p/8875557.html

时间: 2024-10-09 01:38:07

面向对象进阶2:二次加工标准类型(包装)的相关文章

定制自己的数据类型(二次加工标准类型(包装))

---恢复内容开始--- 包装:python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均可以通过下面的方式进行二次加工) 定制了子类List的append,多了类型检查功能 class List(list):#继承list所有的属性,也可以派生出自己新的,比如append和mid def append(self,p_object): '派生自己的append:

二次加工标准类型(包装)

class A: def __init__(self, name): self.name = name def __setitem__(self, key, value): self.__dict__[key] = value def __getitem__(self, item): self.__dict__.get('age') def __delitem__(self, key): print('del obj.__dict__[name]我执行') self.__dict__.pop('

二次加工系统的标准类型 包装与授权

# 二次加工系统的标准类型 # 1.通过继承系统的类来完成包装, 定制自己的数据类型 class List(list): # 定义了一个List类,继承自系统中的list类 def append(self, p_object): # 重写了append方法,改为只能添加字符串 if type(p_object) is str: super().append(p_object) # 因为重写了append,这里要使用原append方类时需要调用父类的append方法,使用super()调用 els

Python学习笔记-面向对象进阶(二)

一.反射 1.什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省). 2.Python面向对象中的反射 通过字符串的形式操作对象相关的属性.python中的一切事物都是对象(都可以使用反射) 3.四个可以实现自省的函数 (1)hasattr(object,name),判断object中有没有一个name字符串对应的方法或属性,检测是否含有某属性. class BlackMedium: feture='Ugly' def _

Python 面向对象进阶

1 isinstance 和issubclass instance:判断该对象是否是类的对象 isinstance(obj,Foo) x = [] print(isinstance(x,list)) 结果:True issubclass:判断是否是继承 class Foo: pass class Bar(Foo): pass print(issubclass(Bar,Foo)) 结果:True 通过下面的方式也可以查看print(Bar.base) 2 反射 反射是Smi首次提出的,主要指程序可

Python全栈开发——面向对象进阶(一切皆对象)

1.isinstance(obj,cls)            检查obj是否是类cls的对象,issubclass(sub,super)          检查sub是否是super的子类 #isinstance(obj,cls) 检查obj是否是类cls的对象 class Foo: pass f=Foo() print(isinstance(f,Foo)) #True #issubclass(sub,super) 检查sub是否是super的子类 class Bar(Foo): pass

Python面向对象进阶和socket网络编程-day08

写在前面 上课第八天,打卡: 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __init__(self,name): self.name=name p = Chinese('standby') # 实例化一个对象 print(p) # 打印这个对象 --- <__main__.Chinese object at 0x0000000000B3A978> - 示例2: >&g

【Python3之面向对象进阶】

一.isinstance和issubclass 1.isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object): pass obj=Foo() print(isinstance(obj, Foo)) 输出 True 2.issubclass(sub, super)检查sub类是否是 super 类的派生类 class Foo(object): pass class Bar(Foo): pass print(issubclass(Bar, Fo

Python学习之面向对象进阶

面向对象进阶当然是要谈谈面向对象的三大特性:封装.继承.多态 @property装饰器 python虽然不建议把属性和方法都设为私有的,但是完全暴露给外界也不好,这样,我们给属性赋值的有效性九无法保证,因此,为了使得对属性的访问既安全又方便,可以通过属性的getter(访问器)和setter(修改器)方法进行对应的操作,在python中,可以考虑使用@property包装器来包装getter和setter方法 class Person(object): def __init__(self,nam