生成器中的Yield语句导致跳过cod行

2024-04-25 00:58:24 发布

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

我正在用python编写一个生成器。它的行为很奇怪,如果我把yield语句放在原处,那么永远不会调用函数顶部的print函数。如果删除yield函数,print语句将按预期进行。目前这是代码。你知道吗

def eachMovement(self):
        print "Each Movement..."

        if not self.isComplete():
            raise ValueError("DressageScore.eachMovement:  dressage score must be designated as complete.")

        for i in range(0, len(self.__iMovementScores)):
            yield (self.__iMovementScores[i], self.__iMovementComments[i])

删除yield可以解决此问题。我做错什么了?为了澄清,我运行的是python2.7.5。请不要说服我用另一种方法来做这件事,我的课要求使用发电机。谢谢!你知道吗

解决方案: 因为我在做测试驱动开发,所以在编写函数的其余部分之前,我编写了raisevalueerror测试。在将每个动作完全转换为生成器之后,我的测试用例失败了,因为它没有设置为测试生成器。我犯了个愚蠢的错误。下面是一个测试用例,它现在完成了,没有问题。谢谢你的帮助

def test1300_910_EachMovementNotComplete(self):
    myGen = self.dsRider.eachMovement()

    self.assertRaises(ValueError, myGen.next)

Tags: 函数代码selfdef测试用例语句eachprint
3条回答

我怀疑你只是打电话给my_obj.eachMovement(),对吗?你知道吗

与函数不同,生成器执行一种称为“延迟求值”的操作。基本上,Python将避免遍历函数,直到它完全需要为止(这很有用,因为它允许您编写返回无限多元素的生成器,允许用户只获取他们需要的内容,而普通函数会阻塞类似的输入)。你知道吗

你需要这样做:

>>> my_gen = my_obj.eachMovement()
>>> print next(my_gen)
Each Movement...
0  # whatever value

…或者类似于:

>>> for i in my_obj.eachMovement():
        print i
Each Movement...
0
1
# etc

这两种方法都将强制Python实际计算生成器,因为它需要数据才能继续工作。你知道吗

如果只调用generator函数,它将返回generator对象,而不会执行该函数。您需要在generator对象上使用next函数,或者可以调用generator对象上的next函数的其他函数,如list。你知道吗

def myGen():
    print "Welcome"
    for i in range(10):
        yield i

print myGen()
print list(myGen())
print next(myGen())

输出

<generator object myGen at 0x7f1548366aa0>
Welcome
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Welcome
0

通常情况下,生成器用于迭代(因为一旦生成器耗尽,它就不可用了)。必须为下一次迭代创建一个新的生成器对象。),因此最佳用法如下

for num in myGen():
    print num

输出

Welcome
0
1
2
3
4
5
6
7
8
9

Python中的yieldlazy evaluation的一种样式,简而言之,这意味着序列中的连续元素只在需要时执行。你知道吗

例如,内置的Python(2.7)函数xrange是一个生成器,Python对懒惰的求值器的术语。你知道吗

正如使用xrange一样,您需要使用函数:

for movement in eachMovement:
    # Do stuff with movement

相关问题 更多 >