2007-08-27

 

Python 学习:扩展Python的列表--Array

Python默认的List类型可以做为数组来使用,可是它有一些特点:

1.允许负索引,这是一般的Array类型所不允许的.
2.只能从0开始索引,有时候我们需要从一个特定的数字开始索引.

我们首先来构造一个简单的Array类型,它有两个简单的属性:
_data:用于保存数据
_baseIndex:用于保存起始索引号

写下下面的类:

class Array(object):
    def __init__(self,length = 0,baseIndex = 0):
        assert length >= 0
        self._data = [None for x in xrange(length)]
        self._baseIndex = baseIndex

该类可以接收两个参数,一个是初始的长度,另一个是起始的索引数.默认是0 .
接下来,我们定义Array的拷贝函数.这样,以后我们就可以这样使用它:

import copy
a = Array(5)
b = copy.copy(a)

为了实现这个功能,我们需要定义__copy__函数,这样,在使用copy的时候,就能调用我们的拷贝函数:

    def __copy__(self):
        result = Array(len(self._data),self._baseIndex)
        for i,item in enumerate(self._data):
            result._data[i] = item
        return result

为了像列表一样,使用[]来访问元素,我们需要定义两个函数:__getattr__和__setattr__,当索引值不存在时,也要报出异常,为了计算出合适的索引,再定义一个getOffset函数:

    def getOffset(self,index):
        offset = index - self._baseIndex
        if offset < 0 or offset >= len(self._data):
            raise IndexError
        return offset
    def __getattr__(self,index):
        return self._data[self.getOffset(index)]
    def __setattr__(self,index,value):
        self._data[self.getOffset(index)] = value

这样,我们就能像访问列表一样访问Array的元素.

同时,为了给用户提供获得Array信息的能力,我们提供了两个属性(property),data和baseIndex,定义属性,可以使用fget和fset访问器:

    def getData(self):
        return self._data
    data=property(
        fget = lambda self: self.getData())
    def getBaseIndex(self):
        return self._baseIndex
    def setBaseIndex(self,index):
        self._baseIndex = index
    baseIndex=property(
        fget = lambda self: self.getBaseIndex(),
        fset = lambda self,index: self.setBaseIndex(index))

我们为Array定义修改大小的接口.
为此,我们首先为Array提供获得长度的接口__len__,然后可以定义fget和fset访问器.

    def __len__(self):
        return len(self._data)
    def setLenght(self,value):
        if len(self._data)!=value:
            newData = [None for i in xrange(value)]
            m = min(len(self._data),value)
            for i in xrange(m):
                newData[i] = self._data[i]
            self._data = newData
    length=property(
        fget = lambda self: self.__len__(),
        fset = lambda self,value: self.setLenght(value))

至此,一个简单的扩展的Array类型就定义完毕了.


标签:


Comments: 发表评论



<< Home

This page is powered by Blogger. Isn't yours?