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。作成されたものには、すべて同じ長さのMatrix複数のが含まれている必要があります。Dimこれらの各には、すべて同じ長さのDim複数のが含まれている必要があります。最後の、数字を含むものは、数字のみを含み、の代わりになります。DimDimVecDim
問題:
リストの場合、これはすべて機能します。ただし、代わりにイテレータオブジェクト(によって返されるオブジェクトなど)を使用した場合、iter()これは希望どおりに機能しません。
例えば:
>>> startingList = [[1,2,3],[4,5,6],[7,8,9]]
>>> matrix.Matrix(iter(startingList))    
[]
私の考え:
これが起こっていることはかなり確信しています。なぜならDim.__new__、入力iterableを反復処理すると、同じiterableが渡されたときに、Matrix.__init__すでに反復処理されているため、空のように見えて、空の行列が得られるからです。
を使用してイテレータをコピーしようとしましたitertools.tee()が、実際には呼び出さないため、リターンMatrix.__init__時に暗黙的に呼び出されMatrix.__new__、に渡されたパラメータとは異なるパラメータで呼び出すことができないため、これも機能しませんMatrix.__init__。私がやろうと思ったことはすべて、これと同じ問題に直面します。
既存の機能を保持matrix.Matrix()し、イテレータオブジェクトで呼び出すことを許可する方法はありますか?