1 回答
TA贡献1993条经验 获得超5个赞
在我看来,您想定义自己的容器类型。
我尝试提供一些标准方法的示例
(希望不会遗漏太多细节);
您应该能够将这些简单示例之一重用
到您自己的课程中。
仅使用 __getitem__ (支持索引和循环):
对象.__getitem__
被调用以执行对自我[key]的评估。
class MyContainer:
def __init__(self, sequence):
self.elements = sequence # Just something to work with.
def __getitem__(self, key):
# If we're delegating to sequences like built-in list,
# invalid indices are handled automatically by them
# (throwing IndexError, as per the documentation).
return self.elements[key]
t = (1, 2, 'a', 'b')
c = MyContainer(t)
elems = [e for e in c]
assert elems == [1, 2, 'a', 'b']
assert c[1:-1] == t[1:-1] == (2, 'a')
使用迭代器协议:
对象.__iter__
object.__iter__(self)
当容器需要迭代器时调用此方法。此方法应返回一个新的迭代器对象,该对象可以迭代容器中的所有对象。对于映射,它应该遍历容器的键。
迭代器对象也需要实现这个方法;他们必须自己返回。有关迭代器对象的更多信息,请参阅迭代器类型。
迭代器类型
container.__iter__()
返回一个迭代器对象。该对象需要支持下面描述的迭代器协议。
迭代器对象本身需要支持以下两种方法,它们共同构成了迭代器协议:
iterator.__iter__()
返回迭代器对象本身。这是允许容器和迭代器与 for 和 in 语句一起使用所必需的。iterator.__next__()
从容器中返回下一个项目。如果没有其他项目,则引发 StopIteration 异常。
一旦迭代器的 __next__() 方法引发 StopIteration,它必须在后续调用中继续这样做。
class MyContainer:
class Iter:
def __init__(self, container):
self.cont = container
self.pos = 0
self.len = len(container.elements)
def __iter__(self): return self
def __next__(self):
if self.pos == self.len: raise StopIteration
curElem = self.cont.elements[self.pos]
self.pos += 1
return curElem
def __init__(self, sequence):
self.elements = sequence # Just something to work with.
def __iter__(self):
return MyContainer.Iter(self)
t = (1, 2, 'a', 'b')
c = MyContainer(t)
elems = [e for e in c]
assert elems == [1, 2, 'a', 'b']
使用发电机:
发电机类型
Python 的生成器提供了一种实现迭代器协议的便捷方式。如果一个容器对象的iter () 方法被实现为一个生成器,它将自动返回一个迭代器对象(技术上,一个生成器对象)提供 iter ( ) 和next () 方法。
发电机
返回生成器迭代器的函数。它看起来像一个普通函数,只是它包含 yield 表达式,用于生成一系列可在 for 循环中使用的值,或者可以使用 next() 函数一次检索一个值。
通常指代生成器函数,但在某些情况下可能指代生成器迭代器。
生成器迭代器
由生成器函数创建的对象。
6.2.9. 产量表达式
在函数体中使用 yield 表达式会使该函数成为生成器
class MyContainer:
def __init__(self, sequence):
self.elements = sequence # Just something to work with.
def __iter__(self):
for e in self.elements: yield e
t = (1, 2, 'a', 'b')
c = MyContainer(t)
elems = [e for e in c]
assert elems == [1, 2, 'a', 'b']
添加回答
举报