I'm trying to write a Python module to handle matrices. (I know about numpy, this is just for fun)
So far I have written a few classes, Matrix
, Dim
, and Vec
. Matrix
and Vec
are both subclasses of Dim
. When creating a matrix, one would first start out with a list of lists and they would create a matrix like:
startingList = [[1,2,3],[4,5,6],[7,8,9]]
myMatrix = matrix.Matrix(startingList)
This should create a Matrix
. The created Matrix
should contain multiple Dim
s all of the same length. Each of these Dim
s should contain multiple Dim
s all of the same length, etc. The last Dim
, the one that contains numbers, should contain only numbers and should be a Vec
instead of a Dim
.
So far this works as I want it to. Here is what I have:
from numbers import Number
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):
# Make sure inDim is iterable
iter(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)
# 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')
# Actually create the Dim because it passed all the tests
return list.__new__(cls,inDim)
def __init__(self,inDim):
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)
This works, but as I have little experience overriding __new__()
I'm fairly certain that this could be better. How can I improve this? Answers need not be specific to use of __new__
and __init__
, but that is what I care most about.