1 回答

TA貢獻1993條經驗 獲得超6個贊
在我看來,您想定義自己的容器類型。
我嘗試提供一些標準方法的示例
(希望不會遺漏太多細節);
您應該能夠將這些簡單示例之一重用
到您自己的課程中。
僅使用 __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']
添加回答
舉報