Python自定义类及内存缓冲操作

来源:互联网 发布:数据网关 英文 编辑:程序博客网 时间:2024/06/05 19:06
Python不直接支持对缓存操作,同时内存中数据的存储也是文本格式表示,这样造成在对二进制数据进行处理时不是很方便。但Python并没有将这条路 封掉,对缓存的读写可以通过StringIO库进行,不过对二进制数据操作时要用struct进行封装或解封。这样一来,在整个操作过程就会比较麻烦。
这几天自己试也下将StringIO和struct库重做成一个对缓存操作的库,也可以试下Python的类操作。

#! /usr/bin/env python
#! -*- coding:utf-8 -*-

#mybuffer.py

class myBuffer:
    '''定义内存缓存操作类'''
    import struct   as _stc
    import cStringIO as _cio
    #----------------------------------
    class _asInt4:
        '''作为子类,将指定位置的数据作为整型值读出或写入'''
       
        def __init__(self):
            pass
        #-------------------
        def __getitem__(self,pos):
            myBuffer._buf.seek(pos,0)
            i= myBuffer._buf.read(4)
            if (len(i)==4):
                ii=myBuffer._stc.unpack('l',i)
                return ii[0]
            else:
                i=i+'/x00/x00/x00/x00'
                ii=myBuffer._stc.unpack('l',i[0:4])
                return ii[0]
        #-------------------
        def __setitem__(self,pos,value):
            myBuffer._buf.seek(0,2)
            l= myBuffer._buf.tell()
            if (l > pos):
                 myBuffer._buf.seek(pos,0)
            myBuffer._buf.write(myBuffer._stc.pack('l',value))
        #--------------------
    _buf=_cio.StringIO()
    asInt=_asInt4()   
    #----------------------------------   
    def __init__(self,buf1):
        self._buf.seek(0,0)
        self._buf.write(buf1)
    #----------------------------------
    def __getattr__(self,name):
        if (name == 'asInt2'):
            i=self._buf.read(4)
            if (len(i)==4):
                ii=myBuffer._stc.unpack('l',i)
                return ii[0]           
            else:
                i=i+'/x00/x00/x00/x00'
                ii=myBuffer._stc.unpack('l',i[0:4])
                return ii[0]           
        else:
            raise (AttributeError,name)
    #----------------------------------
    def __setattr__(self,name,value):
        if (name=='asInt2'):
            self._buf.write(self._stc.pack('l',value))       
        else:
            raise (AttributeError,name)               
    #----------------------------------
    def __getitem__(self,pos):
        self._buf.seek(0,2)
        l= self._buf.tell()
        if (l > pos):
            self._buf.seek(pos,0)   
        self._buf.seek(pos,0)
        return self
上面代码的操作结果

>>> import mybuffer
>>> a=mybuffer.myBuffer('/x01')
>>> a.asInt[0]
1
>>> a[0].asInt2
1
>>> a.asInt[0]=3
>>> a.asInt[0]
3
>>> a[0].asInt2
3
>>> a[0].asInt2=9
>>> a.asInt[0]
9
>>>
看得出,利用实例化后的myBuffer利用下标可以十分方便直接对缓存进行读写,就像C下面的数组。上面的代码只完成整数类型,其它类型的操作可以在基础上进行扩展。


对缓存的操作使用了两种实现。从操作结果可以看出两种操作方式的不同
a.asInt[0]和a[0].asInt2
前面一种方法使用了嵌套子类的方法实现对数据类型的转换引用。
后面一种方法使用类的属性进行访问并实现数据类型的转换。
但这两种方法都使用到类的重载,包括函数重载和运算符重载。

Python对于重载和自定属性都比较简单。

比较麻烦的是类的封装,为了使类封装得更好,选择合适的位置十分重要,另外一个原因是Python是解释性编程语言,同时不用声明变量,语句的序列也就变得十分重要。为了找到合适的布局,我试很久才得到现在这样的布局,不知道还有没有更好的,特别是与类嵌套相关。

上面的代码在载入StringIO和struct库时并没有在全局位置载入,只在myBuffer类中才载入。

class myBuffer:
    '''定义内存缓存操作类'''
    import struct   as _stc
    import cStringIO as _cio