【发布时间】:2016-05-24 04:34:09
【问题描述】:
我试图理解(并最终使用)对象数组的实现,使用来自 numpy 的记录数组从这里:Numpy object array 在审查代码时,我显然正在学习关于 python 的新东西,我似乎无法完全理解以下:
在 obarray.py 文件中,一个函数用于创建一个新对象,我对此感到困惑
- 为什么要使用函数,
- 参数如何在函数中发挥作用,
- 使用此函数与直接使用参数创建类有何不同(可能使用参数作为属性),以及
- 这是什么main.Obarray 我刚刚调用该函数时得到的?
对于 1 和 2,我有一种预感,即参数会以某种方式成为对象的“本地范围”,并且可能类似于对象属性?
这是链接中新对象的代码:
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)])
- 当我调用 FooArray 时,我得到
__main__.Obarray- 这是什么? - 作为参数输入的“klass”和“dtype”发生了什么变化?
- 这与以下内容有何不同:
块引用
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
【问题讨论】:
-
我不确定您的困惑是特定于这个
numpy代码还是更一般的。你了解闭包的工作原理吗?你以前用过collections.namedtuple这样的类型工厂吗? -
这是此代码中出现的一个更普遍的问题,因此我将其用作示例。是的,我熟悉 namedtuple,但是 namedtuple 是不可变的
标签: python arrays inheritance numpy metaprogramming