我正在寻找一个模拟Python中不可变序列的类的最小示例。
class MySequence()
...
a = MySequence()
len(a)
for i in a:
pass
a[0]
必须实施哪些方法?
答案 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()