可分叉迭代器-Python中有它的实现吗



我所说的"可分叉迭代器"是指一个带有方法fork()的常规迭代器,它创建了一个新的迭代器从原始迭代器的当前迭代点开始迭代。即使原始迭代器被进一步迭代,fork也会停留在它被分叉的地方,直到它本身不会被迭代为止。

我的实际用例:我有一个套接字连接,还有一些通过它发送的"数据包"。连接可以在"接收器"之间共享,每个"包"都可以寻址到某个"接收器"。"数据包"可以以无序的方式出现,因此每个"接收器"都可能接收不同"接收器"的数据包。更重要的是,如果一个"接收器"接收到不同"接收器"的"数据包",这个"不同的接收器"必须仍然能够读取该数据包。

因此,我想实现这样的可分叉迭代器,它将代表连接,每个接收器将制作自己的分叉,读取它并搜索为它寻址的"数据包"

有人知道我所说的任何实现吗?

您正在寻找itertools.tee()函数:

从单个可迭代项返回n独立迭代器。

请考虑实现将缓冲数据以服务于所有子迭代器:

这个迭代工具可能需要大量的辅助存储(取决于需要存储多少临时数据)。

此外,您应该只使用返回的子迭代器;对源迭代器进行迭代将不会将数据传播到tee()可迭代项。

这是我目前实现的可分叉迭代器:

#!/usr/bin/env python
# coding=utf-8
from collections import Iterator, deque
import threading

class ForkableIterator(Iterator):
    def __init__(self, iterator, buffer=None, *args, **kwargs):
        self.iterator = iter(iterator)
        if buffer is None:
            self.buffer = deque()
        else:
            self.buffer = buffer
        args = iter(args)
        self.refs = kwargs.get('refs', next(args, {}))
        self.refs.setdefault('base', 0)
        self.pointer = kwargs.get('pointer', next(args, 0))
        self.lock = kwargs.get('lock', next(args, threading.Lock()))
    @property
    def pointer(self):
        return self.refs[self] + self.refs['base']
    @pointer.setter
    def pointer(self, value):
        self.refs[self] = value
    def __del__(self):
        del self.refs[self]
    def __iter__(self):
        return self
    def next(self):
        with self.lock:
            if len(self.buffer) - self.pointer == 0:
                elem = next(self.iterator)
                self.buffer.append(elem)
            else:
                if self.pointer == min(self.refs.itervalues()):
                    elem = self.buffer.popleft()
                    self.refs['base'] -= 1
                else:
                    elem = self.buffer[self.pointer]
            self.pointer += 1
            return elem
    def fork(self):
        return self.__class__(self.iterator, self.buffer,
                              refs=self.refs, pointer=self.pointer,
                              lock=self.lock)

相关内容

  • 没有找到相关文章

最新更新