我正在尝试编写一个 python (2.7) 矩阵模块。(我知道 numpy,这只是为了好玩。)
我的代码:
from numbers import Number
import itertools
test2DMat = [[1,2,3],[4,5,6],[7,8,9]]
test3DMat = [[[1,2,3],[4,5,6],[7,8,9]],[[2,3,4],[5,6,7],[8,9,0]],[[9,8,7],[6,5,4],[3,2,1]]]
class Dim(list):
def __new__(cls,inDim):
# If every item in inDim is a number create a Vec
if all(isinstance(item,Number) for item in inDim):
#return Vec(inDim)
return Vec.__new__(cls,inDim)
# Otherwise create a Dim
return list.__new__(cls,inDim)
def __init__(self,inDim):
# Make sure every item in inDim is iterable
try:
for item in inDim: iter(item)
except TypeError:
raise TypeError('All items in a Dim must be iterable')
# Make sure every item in inDim has the same length
# or that there are zero items in the list
if len(set(len(item) for item in inDim)) > 1:
raise ValueError('All lists in a Dim must be the same length')
inDim = map(Dim,inDim)
list.__init__(self,inDim)
class Vec(Dim):
def __new__(cls,inDim):
if cls.__name__ not in [Vec.__name__,Dim.__name__]:
newMat = list.__new__(Vec,inDim)
newMat.__init__(inDim)
return newMat
return list.__new__(Vec,inDim)
def __init__(self,inDim):
list.__init__(self,inDim)
class Matrix(Dim):
def __new__(cls,inMat):
return Dim.__new__(cls,inMat)
def __init__(self,inMat):
super(Matrix,self).__init__(inMat)
当前功能:
到目前为止,我已经写了几个类,Matrix
,Dim
, 和Vec
。Matrix
并且Vec
都是 的子类Dim
。创建矩阵时,首先会从列表列表开始,然后他们会创建一个矩阵,如下所示:
>>> startingList = [[1,2,3],[4,5,6],[7,8,9]]
>>> matrix.Matrix(startingList)
[[1,2,3],[4,5,6],[7,8,9]]
这应该创建一个Matrix
. createdMatrix
应该包含多个Dim
长度相同的 s。这些Dim
s 中的每一个都应该包含多个Dim
长度相同的 s,等等。最后Dim
一个包含数字的 s 应该只包含数字,并且应该是 aVec
而不是 a Dim
。
问题:
所有这些都适用于列表。但是,如果我要使用迭代器对象(例如返回的对象iter()
),则它不会像我想要的那样起作用。
例如:
>>> startingList = [[1,2,3],[4,5,6],[7,8,9]]
>>> matrix.Matrix(iter(startingList))
[]
我的想法:
我相当肯定这正在发生,因为在Dim.__new__
我迭代输入迭代时,当相同的迭代被传递给Matrix.__init__
它时,它已经被迭代,因此看起来是空的,导致我得到空矩阵。
我尝试使用 复制迭代器itertools.tee()
,但这也不起作用,因为我实际上并没有调用Matrix.__init__
它在返回时被隐式调用Matrix.__new__
,因此我不能使用与传递给的参数不同的参数来调用它Matrix.__init__
。我想做的所有事情都遇到了同样的问题。
我有什么方法可以保留现有功能并允许matrix.Matrix()
使用迭代器对象进行调用?