Pippi
Pippi

Reputation: 2571

How to use yield in python to defer evaluation in a conditional statement?

I wish to use yield inside an if statement to defer evaluation of a callback function. If I do the following:

def callback(): 
    print "hi yield"

class dicTest(): 
    e = {}

    def eval(self): 
        yield callback()  

and call:

d = dicTest() 
gen = d.eval()
gen.next() 
gen = d.eval() 
gen.next() 
gen.next()

Then the last gen.next() generates the exception, as expected. However, I need to do this:

def callback(): 
    print "hi yield"

class dicTest(): 
    e = {}

    def eval(self, cond): 
        if cond: 
            print "eval true"
        else: 
            yield callback() 

The test is below:

d = dicTest() 
cond = True 
gen = d.eval(cond)
print "next eval" 
gen.next() 
print "next cond"
cond = False 
print "next eval false"
gen = d.eval(cond) 
gen.next() 
gen.next() 

result from the test:

next eval
eval true
Traceback (most recent call last):
  File "little.py", line 43, in <module>
    gen.next() 
StopIteration

Why does this generates an exception? How to fix this?

Upvotes: 0

Views: 1333

Answers (1)

Michael S Priz
Michael S Priz

Reputation: 1126

I think you misunderstood how yield works. yield returns a value but saves the state of the generator. So the next time you call gen.next() the generator will pick up where it left off.

In your case when cond is true you print something but never actually yield a value. I think what you want is:

if cond: 
    print "eval true"
    yield "" # Some dummy value
yield callback() 

Note that here when cond is true there is an additional yield before the callback. The generator will have to call next one more time in order to consume that first yield and get to the callback.

Upvotes: 2

Related Questions