views:

120

answers:

2

Can I add a member variable / method to a Python generator?

I want something along the following lines, so that I can "peek" at member variable j:

def foo():
    for i in range(10):
        self.j = 10 - i
        yield i

gen = foo()
for k in gen:
    print gen.j
    print k

Yes, I know that I can return i AND j every time. But I don't want to do that. I want to peek at a local within the generator.

+2  A: 

I think it's ugly, but it should do what you want. I'd rather return i AND j every time, though :-)

class Foo(object):
    def foo(self):
        for i in range(10):
            self.j = 10 - i
            yield i

genKlass = Foo()
gen = genKlass.foo()
for k in gen:
    print genKlass.j
    print k
Davide
Personally I too would rather simply return i and j, probably in a tuple, rather than hack things together to work.
Dustin
I think there are wider advantages to what Joseph is requesting, in scenarios where a generator may be manipulated while it's being populated, such as a queue of network tasks. in that case depending on the tuple is not a viable alternative.
Fire Crow
+6  A: 

You could create an object and manipulate the __iter__ interface:

class Foo(object):
    def __init__(self):
        self.j = None
    def __iter__(self):
        for i in range(10):
            self.j = 10 - i
            yield i

my_generator = Foo()

for k in my_generator:
    print 'j is',my_generator.j
    print 'k is',k

Prints:

j is 10
k is 0
j is 9
k is 1
j is 8
k is 2
j is 7
k is 3
j is 6
k is 4
j is 5
k is 5
j is 4
k is 6
j is 3
k is 7
j is 2
k is 8
j is 1
k is 9
Ross Rogers