如何实现一个像Python中的序列一样的最小类?

时间:2011-10-24 12:52:43

标签: python sequence

我正在寻找一个模拟Python中不可变序列的类的最小示例。

class MySequence()
    ...

a = MySequence()

len(a)

for i in a:
    pass

a[0]

必须实施哪些方法?

2 个答案:

答案 0 :(得分:11)

如果您只是希望能够迭代序列,则只需要实现返回iterable的__iter__方法。最简单的方法是使用yield语句创建生成器。

class MySequence(object):
    def __iter__(self):
        yield 1
        yield 2
        yield 3

for x in MySequence():
    print x # prints 1, then 2, then 3

但是,这不会启用MySequence()[1]之类的内容。为此,您需要实现__getitem__方法,并且可能也应该实现__len__

class MySequence(object):
    def __len__(self):
        return 3

    def __getitem__(self, key):
        if key == 0:
            return 1
        elif key == 1:
            return 2
        elif key == 2:
            return 3
        else:
            raise IndexError()

s = new MySequence()

for i in range(len(s)):
    print s[i] # prints 1, then 2, then 3

for x in s:
    print x # prints 1, then 2, then 3

请注意,我省略了__iter__。只要__getitem__在尝试获取超出范围的值时引发IndexError,Python就可以使用它进行迭代。 (如果我想更清楚,或者想要非标准的迭代行为,我仍然可以包含__iter__。)

答案 1 :(得分:0)

添加到@Jeremy的答案:普遍认为值是一般序列是使用isinstance(value, collections.Sequence)

为了使它适用于您的类型,它需要从collections.Sequence继承,并且实际上,只要您提供{{1},它就会为mixin提供迭代器(和其他有用的功能)。 }和__len__函数。

借用@Jeremy的答案,示例类如下:

__index__

用法示例:

import collections
class MySequence(collections.Sequence):
    def __len__(self):
        return 3

    def __getitem__(self, key):
        if key == 0:
            return 1
        elif key == 1:
            return 2
        elif key == 2:
            return 3
        else:
            raise IndexError()