“双”迭代器和生成函数

2024-10-03 04:32:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用类似迭代器的对象获取“next asset”,但是(不是__next__()方法)有两种算法加载next asset(next1next2),它们可以作为“准迭代器”实现,如:

class AssetLoader(object):
    def __init___(self):
        pass

    def next1(self):
        # ...

    def next2(self):
        # ...

要清楚的是,下一个检索到的对象可能取决于调用next1next2的“历史”,例如:

next1()next1()next2()next1()next2()

我的问题是:这(迭代器中的两种“下一步”)是否可以实现为一个生成器函数?你知道吗

我想这可以通过函数引用的全局变量来实现。但是它可以不使用全局变量,而使用一些局部变量吗?你知道吗

如果用当前的Python很难或不可能,我们可以讨论如何向Python添加新的语义以使之成为可能吗?你知道吗


Tags: 对象方法函数self算法objectinitdef
2条回答

你可以试试这个:

class AssetLoader(object):
    def __init___(self):
        self.current_next = self.next1

    def next1(self):
        if condition:
            self.current_next = self.next2
        elif conition:
            return x
        else:
            raise StopIteration

    def next2(self):
        if condition:
            self.current_next = self.next1
        elif conition:
            return y
        else:
            raise StopIteration

    def __next__(self):
        return self.current_next()

    def __iter__(self):
        return self

下面是一个使用send在两种不同的迭代模式之间切换生成器的简单示例:它要么增加当前值,要么将当前值相乘。同样的原理也可以应用于图形遍历任务。你知道吗

send方法允许您将对象发送到生成器中。恼人的是,send的结果是通过调用next可以获得的当前值;如果您可以发送而不让生成器生成一个值,那会很好,但这正是我们必须面对的问题。你知道吗

def add_or_mul(current, step, scale, mode='add'):
    ''' A generator that either adds step to the current value,
        or multiplies it by scale
    '''
    while True:
        newmode = yield current
        if newmode is not None:
            if newmode not in ('add', 'mul'):
                raise ValueError('Bad mode: ' + newmode)
            mode = newmode
        if mode == 'add':
            current += step
        else:
            current *= scale

# Test

    gen = add_or_mul(1, 1, 2)
    for i in range(5):
        print(next(gen))
    print(gen.send('mul'))
    for i in range(4):
        print(next(gen))
    print(gen.send('add'))
    for i in range(4):
        print(next(gen))       

输出

    1
    2
    3
    4
    5
    10
    20
    40
    80
    160
    161
    162
    163
    164
    165

如果您在将此技术应用于图形遍历任务时遇到问题,请提出一个新问题(可能链接到此问题),其中包括一些相关的图形代码,这样回答者就不必从头开始编写这些内容来测试和演示他们的代码。你知道吗

相关问题 更多 >