是否有一個Iterable對象可以持有的鉤子/dunder,以便內置filter函數可以擴展到Iterable類(而不僅僅是實例)?當然也可以自己寫一個自定義filter_iter函數,比如:def filter_iter(filt_func: callable, collection_cls: type): name = 'Filtered' + collection_cls.__name__ # would this automatic scheme lead to namespace conflicts? wrapped_cls = type(name, (collection_cls,), {'_filt_func': staticmethod(filt_func)}) def __iter__(self): yield from filter(self._filt_func, super(wrapped_cls, self).__iter__()) wrapped_cls.__iter__ = __iter__ return wrapped_cls這會產生預期的效果。例如,from collections import Collection, Iterableclass Chunker(Iterable): def __init__(self, source: Iterable, chk_size: int=2): self._source = source self._chk_size = chk_size def __iter__(self): yield from zip(*([iter(self._source)] * self._chk_size))chunker = Chunker(range(12), 2)assert list(chunker) == [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, 11)]FilteredChunker = filter_iter(lambda x: sum(x) % 3 == 0, Chunker)filtered_chunker = FilteredChunker(range(12))assert list(filtered_chunker) == [(4, 5), (10, 11)]但是,就像有一個__iter__鉤子可以確定如何迭代一個對象(例如,list在對象上調用時應該如何表現),是否有一種__filter__鉤子可以確定filter在該對象上調用時應該如何表現?如果不是,關于過濾可迭代對象的最佳實踐或標準是什么?
1 回答

泛舟湖上清波郎朗
TA貢獻1818條經驗 獲得超3個贊
與list(__iter__例如)不同,沒有這樣的掛鉤filter。后者只是迭代器協議的一個應用,而不是一個單獨的協議本身。
為了不讓您空手而歸,這是 filtered_iter您提出的一個更簡潔的版本,它動態地對給定類進行子類化,將其__iter__方法與filter.
def filter_iter(p, cls):
class _(cls):
def __iter__(self):
yield from filter(p, super().__iter__())
return _
添加回答
舉報
0/150
提交
取消