小能豆

Python 使用嵌套生成器进行操作

python

我有一些这样的代码:

class A:
  def __iter__(self):
    for i in range(100):
      yield i

class B:
  def __init__(self, src):
    self.src = src
  def __iter__(self):
    for i in self.src:
      yield i * 2

class C:
  def __init__(self, src1, src2):
    self.src1 = src1
    self.src2 = src2
  def __iter__(self):
    for i, j in zip(self.src1, self.src2):
      yield i + j

a = A()
b = B(a)
c = C(a, b)
it = iter(c)
next(it)

我想做的是在调用时分解调用链next(it)。更具体地说,我想yield在每个类之后执行一些新代码,而不修改类代码。理想情况下,新代码会打印在哪个类中yield执行。这是可能的事情吗?


阅读 146

收藏
2023-07-28

共1个答案

小能豆

是的,您可以在不修改类代码的情况下在每个类的 yield 后执行一些新代码。这可以通过创建一个包装器类来实现,该包装器类接受源迭代器并在 yield 后执行附加代码。

以下是一个示例,展示了如何创建这样的包装器类:

class A:
    def __iter__(self):
        for i in range(100):
            yield i

class B:
    def __init__(self, src):
        self.src = src

    def __iter__(self):
        for i in self.src:
            yield i * 2

class C:
    def __init__(self, src1, src2):
        self.src1 = src1
        self.src2 = src2

    def __iter__(self):
        for i, j in zip(self.src1, self.src2):
            yield i + j

# Wrapper class to print after each yield
class YieldWrapper:
    def __init__(self, iterable):
        self.iterable = iterable

    def __iter__(self):
        it = iter(self.iterable)
        while True:
            try:
                value = next(it)
                yield value
                print(f"Executed after yield: {value}")
            except StopIteration:
                break

a = A()
b = B(a)
c = C(a, b)

# Wrap the original iterators with the YieldWrapper
a_wrapped = YieldWrapper(a)
b_wrapped = YieldWrapper(b)
c_wrapped = YieldWrapper(c)

it = iter(c_wrapped)
next(it)

在上述代码中,我们创建了一个名为 YieldWrapper 的包装器类。这个包装器类接受一个迭代器作为参数并在 __iter__ 方法中使用一个无限循环来迭代原始迭代器。在每次调用 next 后,我们使用 yield 返回原始迭代器的值,并在后面执行一些附加代码(在本例中是打印语句)。

然后,我们在 abc 的实例上创建 YieldWrapper 的实例,从而对每个类的 yield 执行后都添加了打印语句。

请注意,此示例中的包装器类是一个简化版本,仅用于说明概念。在实际使用时,您可能需要考虑更多的边界情况和错误处理。

2023-07-28