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
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:
eintraege.append( deutsch + '-' + englisch )
Here is how I am testing it:
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
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)])
- what is this?Blockquote
__main__.Obarray
答案 0 :(得分:1)
make_obarray
函数是一个生成类的工厂。它返回的类的方法将是可以访问函数的局部变量(例如klass
和dtype
参数)的闭包,即使它已经完成运行。
这是一个更简单的闭包,可以帮助您了解它们的工作原理:
def make_adder(x):
def adder(y):
return x + y
return adder
make_adder
是一个工厂函数。它返回一个adder
函数,它是一个闭包。 adder
即使在x
返回后,make_adder
仍然可以看到定义它的make_adder
调用的numpy
参数。
这与您展示的make_obarray
代码相似。 some_module.Obarray
函数返回一个类,而不是一个函数,但除此之外它几乎相同。该类的限定名称将在Python 2中为some_module.make_obarray.<locals>.Obarray
(或在Python 3中为some_module
),其中__main__
是在其中定义的模块的名称(或{{ 1}}如果您已将其模块作为脚本执行)。返回类的方法将能够看到传递到klass
的{{1}}和dtype
参数,就像make_obarray
函数可以看到adder
参数一样在我更简单的例子中x
。
至于为什么你发现的代码是这样编写的,我无法说出来。也许代码的作者认为能够使用make_adder
区分isinstance
具有不同Obarray
或klass
值的实例是有用的:
dtype
如果FooArray = make_obarray(Foo, dtype)
BarArray = make_obarray(Bar, some_other_dtype)
f = FooArray([Foo(1,2)])
print(isinstance(f, FooArray)) # True
print(isinstance(f, BarArray)) # False
和klass
只是单个类的参数,那么你就不能以这种方式区分数组实例(尽管你可能想出一个等价物检查是否比较了实例&#39;属性。)