首页 > 解决方案 > 在单个 python 对象中多个类实例

问题描述

我在学术环境中,一直致力于使用 numpy 和 scipy 将我的一些数据分析代码库从 MATLAB 转换为 Python 3.x(Anaconda),以便与一些没有 MATLAB 许可证的合作者合作. 我还用它作为提高我的 python 能力的借口,而不是仅仅将它全部复制到 Octave 并修复任何突然出现的小问题。在这一点上,我已经有了一些使用 python 的基本经验,但是我在用 Python 类复制我的 MATLAB 代码库中的一些数据处理类的行为时遇到了问题。这里所讨论的类基本上包含大量光谱数据以及标识符和一些基本分析。

基本上在 MATLAB 中,我最终得到了该类的 Nx1 实例。这让我可以通过索引父对象来逐个信号地查看事物,我用它来将信号的所有相关数据传递给以后的分析函数。

例如:

% Sample Data
positions = [195, 250, 280];
widths = [5, 5, 10];

Data = DataObject(positions, widths)

>> Data(1)
ans = 
    DataObject with properties:
        value_a: 195
        value_b: 5

它还让我可以轻松地获取所有信号的值,从而可以轻松地将其放入电子表格或报告中。例如

>> [Data.value_a]'
ans = [195, 250, 280]

(注意:我知道在这个例子中它只是返回输入,但在实际代码中也有我关心的派生值。)

我一直在试图弄清楚如何在 python 中复制这种行为,所以理想情况下我可以做这样的事情:

positions = np.array([195, 250, 280])
widths = np.array([5, 5, 10])

Data = DataObject(positions, widths)
>>> Data[1]
<A DataObject containing only the data for the first signal>

>>> Data.value_a
array([195, 250, 280])

我尝试了类似于我在 MATLAB 中所做的事情,方法是使用

for idx in range(len(centers)):
            self[idx].center = centers[idx]

在 __init__ 方法中,但它只是给了我:

TypeError: 'SignalPeak' object is not subscriptable

我已经能够找到关于如何让一个对象的多个实例围绕将它们放在一个列表中的大多数谷歌结果,然后当您想要查看所有这些属性时手动迭代它们。但我想知道是否有一种方法可以更类似于我的原始代码所做的,或者至少将该行为包装到类定义中。

MATLAB 类定义为:

classdef DataObject
    properties
        value_a
        value_b
    end
    methods
        function obj = DataObject(reference, data)
            % reference: a Nx1 vector 
            % data: a Nx1 vector

            obj(size(reference,1),size(reference,2)) = obj; % Creates a Nx1 SignalPeak object

            % Sets the various values
            for idx = 1:length(centers(:))
                obj(idx).value_a = reference(idx)
                obj(idx).value_b = data(idx)
            end
        end    
    end
end

标签: pythonmatlab

解决方案


您可以做一些事情,但我认为没有办法创建一个包装器对象来包装您想要的所有数据对象的列表。这是一个这样的实现:

In [18]: class DataObject:
    ...:     def __init__(self, a, b):
    ...:         self.a = a
    ...:         self.b = b
    ...:     def __str__(self):
    ...:         return "DataObject: a={a}, b={b}".format(a=self.a, b=self.b)

In [19]: o1 = DataObject(1, 2)

In [20]: print(o1)
Out[20]: DataObject: a=1, b=2

In [21]: o2 = DataObject(3, 4)

In [22]: print(o2)
Out[22]: DataObject: a=3, b=4

In [23]: objects = DataObjects()

In [24]: objects.add(o1)

In [25]: objects.data_objects
Out[25]: [<__main__.DataObject at 0x103a0f610>]

In [26]: objects.add(o2)

In [27]: objects.data_objects
Out[27]: [<__main__.DataObject at 0x103a0f610>, <__main__.DataObject at 0x103842bd0>]

In [28]: objects.data_objects[1]
Out[28]: <__main__.DataObject at 0x103842bd0>

In [29]: objects.data_objects[1].a
Out[29]: 3

In [30]: objects.a
Out[30]: [1, 3]

我希望这有帮助!


推荐阅读