views:

276

answers:

2

I have a generator that generates a series, for example:

def triangleNums():
    '''generate series of triangle numbers'''
    tn = 0
    counter = 1
    while(True):
        tn = tn + counter
        yield tn
        counter = counter + 1

in python 2.6 I am able to make the following calls:

g = triangleNums() # get the generator
g.next()           # get next val

however in 3.0 if I execute the same two lines of code I'm getting the following error:

AttributeError: 'generator' object has no attribute 'next'

but, the loop iterator syntax does work in 3.0

for n in triangleNums():
    if not exitCond:
       doSomething...

I've not been able to find anything yet that explains this difference in behavior for 3.0.

+6  A: 

Try:

next(g)

Check out this neat table that shows the differences in syntax between 2 and 3 when it comes to this.

Paolo Bergantino
+4  A: 

Correct, g.next() has been renamed to g.__next__(). The reason for this is to have consistence. Special methods like __init__() and __del__ all have double underscores (or "dunder" as it is getting popular to call them now), and .next() is one of the few exceptions to that rule. Python 3.0 fixes that. [*]

But instead of calling g.__next__(), as Paolo says, use next(g).

[*]There are more special attributes who has gotten this fix, like function attributes. No longer func_name, it's now __name__, etc.

Lennart Regebro
Lennart - thanks for the addition info!
jottos