是否有一个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
提交
取消