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

问题描述 投票:7回答:2

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

class MySequence()
    ...

a = MySequence()

len(a)

for i in a:
    pass

a[0]

有哪些方法必须实施?

python sequence
2个回答
11
投票

如果您只想迭代序列,则只需要实现返回可迭代的__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__。)


0
投票

添加到@ Jeremy的答案:值是一般序列的流行检查是使用isinstance(value, collections.Sequence)

为了使你的类型成为真,它需要从collections.Sequence继承,这实际上为mixins提供了迭代器(以及一些其他有用的函数),只要你提供__len____index__函数。

借用@ Jeremy的答案,一个示例类看起来像:

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()

用法示例:

s = 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

print isinstance(s, collections.Sequence) # prints True

print 1 in s # prints True

print list(reversed(s)) # prints [3, 2, 1]
© www.soinside.com 2019 - 2024. All rights reserved.