如何在Python中将自定义类设置为集合

时间:2015-07-21 01:33:16

标签: python arrays matlab list class

我来自Matlab背景。在matlab中,我可以创建一个类定义,然后创建一个对象数组。我可以使用索引轻松取消引用每个对象。另外,当我从对象数组中调用一个方法(没有索引)时,我可以访问数组中的所有对象。例如,假设myNewClass具有.data和.text属性,它还具有.clob方法。我可以:

% init
a(1) = myNewClass;
a(2) = myNewClass;

a(1).data = [0;0;0];
a(2).data = [1;1;1];

所以现在,如果我调用a.clob(不是(1).clob或(2).clob),我可以做类似的事情

% this is a function inside the methods definition of my class definition
function clob(self)
   % self here is my object array, "a", from above
   for i=1:length(self)
       % deref a single object
       self(i).goClobYourself;
   end
end

我如何在Python中执行此类操作?请注意,我希望我的班级成为一个索引集合,有点像列表。但是,我不想要我的"班级列表"接受任何类,只需myNewClass。如果我继承自" list,"我的班级将成为一个"列表"具有.data,.text和函数.clob属性的类?还要注意,我不想要一个"列表"包含我的对象,我希望我的对象是列表,以便我可以从索引中解析它们:a [1] .clob()或a(1).clob()(??或类似的东西)。或者,我想将整个数组传递给self:a.clob()允许我访问列表。我的术语可能有点混浊。

祝你好运

2 个答案:

答案 0 :(得分:1)

Python中的所有此类功能都使用"特殊方法名称"如语言参考部分3.3中所述。第3.3.6节描述了如何模拟容器类型,这通常是您在这里要求的。您需要定义和实现方法__getitem____setitem____delitem__以及__iter____reversed____contains__。 Python非常适合这种方法,而且方法非常灵活。

答案 1 :(得分:1)

在Python中编程时,执行类型检查并不常见。你是肯定的,你需要你的列表只接受一种类型(及其子类型),或者你会相信程序员阅读你的文档而不是把它放在不应该存在的东西中吗?

如果是这样,这里是一个继承自collections.MutableSequence的示例通用类,它可能会做你想做的事情:

from collections import MutableSequence
class VerifierList(MutableSequence):
    _list = None
    def __init__(self, allowedClasses, *args, **kwargs):
        super(VerifierList, self).__init__()
        self._list = list(*args, **kwargs)
        self.allowedClasses = tuple(allowedClasses)
    def __repr__(self):
        return repr(self._list)
    def __str__(self):
        return str(self._list)
    def __len__(self):
        return len(self._list)
    def __getitem__(self, index):
        return self._list[index]
    def __setitem__(self, index, value):
        if not isinstance(value, self.allowedClasses):
            raise TypeError('Value of type %s not allowed!' % value.__class__.__name__)
        self._list[index] = value
    def __delitem__(self, index):
        del self._list[index]
    def insert(self, index, value):
        if not isinstance(value, self.allowedClasses):
            raise TypeError('Value of type %s not allowed!' % value.__class__.__name__)
        self._list.insert(index, value)

按如下方式使用:

>>> class A(object): pass

>>> class B(object): pass

>>> l = VerifierList((A,))
>>> l.append(A())
>>> print(l)
>>> [<__main__.A object at 0x000000000311F278>]
>>> l.append(B())

Traceback (most recent call last):
  File "<pyshell#228>", line 1, in <module>
    l.append(B())
  File "C:\Python27\lib\_abcoll.py", line 661, in append
    self.insert(len(self), value)
  File "<pyshell#204>", line 23, in insert
    raise TypeError('Value of type %s not allowed!' % value.__class__.__name__)
TypeError: Value of type B not allowed!