我希望使用类似迭代器的对象获取“下一个资源”,但是(而不是__next__()
方法)有两个算法加载下一个资产(next1
和next2
下面) ,可以实现为“准迭代器”,如:
class AssetLoader(object):
def __init___(self):
pass
def next1(self):
# ...
def next2(self):
# ...
要明确的是,下一个检索到的对象可能取决于调用next1
和next2
的“历史记录”,例如:
next1()
; next1()
; next2()
; next1()
; next2()
我的问题:可以将(迭代器中的两种“下一步”)作为生成器函数实现吗?
我想这可以通过函数引用的全局变量来完成。但它可以不使用全局变量,但使用一些局部变量吗?
如果使用当前的Python很难或不可能,我们是否可以讨论如何向Python添加新的语义以使其成为可能?
答案 0 :(得分:3)
这是一个使用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
如果您在将此技术应用于图形遍历任务时遇到问题,请提出一个新问题(可能链接到此问题),其中包含一些相关的图形代码,以便回答者不必从头开始编写这些内容测试并演示他们的代码。
答案 1 :(得分:1)
你可以试试这个:
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