patternpythonMinor
Python __new__ and __init__ usage
Viewed 0 times
__init__usagepythonand__new__
Problem
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,
This should create a
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__]:
newMa
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 Dims all of the same length. Each of these Dims should contain multiple Dims 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__]:
newMa
Solution
First, the thing that was most obvious in your code was that you never used a space after a comma.
Second, you have the Matrix class where you override
That's where I started to wonder why you define a
I would move the tests from
One issue I see is that
In
Last tip, when inheriting types like
Also:
Second, you have the Matrix class where you override
__new__ and __init__, however it would be work just fine if you'd use class Matrix(Dim): pass.That's where I started to wonder why you define a
Dim class and than inherit from it for Matrix and Vec, instead of code Matrix and subclass Vec from it. Any reason?I would move the tests from
Dim.__new__, except for the numbers test, to __init__. The iter test is not needed, you'll get an error from the list constructor or the for loop anyway.One issue I see is that
Matrix('abc') will result in endless recursion, because strings are iterable. Those are the places where I regret the absence of chr type in python :)In
Vec.__new__, I would let others customize the way they inherit from, why do you check if the class is a Vec or a Dim?Last tip, when inheriting types like
list or str, you have to override all the operator overloading methods if you plan on doing things like Vec((0, 1, 2)) * Vec((2, 3, 4))Also:
[Vec.__name__,Dim.__name__] use tuples here, memory managementtest2DMat = [[1,2,3],[4,5,6],[7,8,9]] I would break lines hereContext
StackExchange Code Review Q#17643, answer score: 4
Revisions (0)
No revisions yet.