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类型就定义完毕了.
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类型就定义完毕了.
标签: Python