I am trying to understand (and eventually use) the implementation of object arrays using record arrays from numpy from here: Numpy object array in reviewing the code I am apparently learning new things about python and I can't seem to fully understand the following:
In the obarray.py file a function is used to create a new object and I am confused as to
- Why a function is used,
- How the arguments play into the function,
- How using this function differs from creating the class with the arguments directly and (presumably using the arguments as attributes), and
- What is this main.Obarray I get when I just call the function?
For 1 and 2 I have a hunch that the arguments somehow become that objects "local scope" and are perhaps similar to a object attribute?
Here is the code for the new object from the link:
import numpy as np
def make_obarray(klass, dtype):
class Obarray(np.ndarray):
def __new__(cls, obj):
print "CLS:", cls
print "OBJ:", obj
A = np.array(obj,dtype=np.object)
N = np.empty(shape=A.shape, dtype=dtype)
for idx in np.ndindex(A.shape):
for name, type in dtype:
N[name][idx] = type(getattr(A[idx],name))
return N.view(cls)
def __getitem__(self, idx):
V = np.ndarray.__getitem__(self,idx)
if np.isscalar(V):
kwargs = {}
for i, (name, type) in enumerate(dtype):
kwargs[name] = V[i]
return klass(**kwargs)
else:
return V
def __setitem__(self, idx, value):
if isinstance(value, klass):
value = tuple(getattr(value, name) for name, type in dtype)
# FIXME: treat lists of lists and whatnot as arrays
return np.ndarray.__setitem__(self, idx, value)
return Obarray
Here is how I am testing it:
class Foo:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return "<Foo a=%s b=%s>" % (self.a, self.b)
dtype = [("a",np.int),
("b",np.float)]
FooArray = make_obarray(Foo, dtype)
A = FooArray([Foo(0,0.1),Foo(1,1.2),Foo(2,2.1),Foo(3,3.3)])
- When I call FooArray I get
__main__.Obarray- what is this? - What happened to "klass" and "dtype" that I entered as arguments?
- How is this different from something along the lines of:
Blockquote
class Obarray(np.ndarray):
def __new__(cls,input_array, klass, dtype):
obj = np.assarray(input_array).view(cls)
obj.klass = klass
obj.dtype = dtype
A = np.array(obj,dtype=np.object)
N = np.empty(shape=A.shape, dtype=dt ype)
for idx in np.ndindex(A.shape):
for name, type in dtype:
N[name][idx] = type(getattr(A[idx],name))
obj.N = N.view(np.ndarray)
return obj
numpycode or more general. Do you understand how closures work? Have you ever used a type-factory likecollections.namedtuplebefore?