trouble with generators

Hans-Peter Jansen hpj at urpla.net
Thu May 10 08:52:39 EDT 2007


Hi Pythonistas,

I'm stuck in a maze of new style classes and generators. While I love the
concepts, I obviously didn't grok them throughout. 

I'm trying to generate a bunch of similar classes, where some are contained
in list attributes of others, e.g.: 

class A:
  def __init__(self):
    self.id = 'A1'
    self.b = [instances of B]

class B:
  def __init__(self):
    self.id = 'B1'

Here's the test code, I have:

#!/usr/bin/env python
# -*- coding: utf8 -*-

class A(object):
    "A"
    def __init__(self):
        self.id = None
        self.b = []

class B(object):
    "B"
    def __init__(self):
        self.id = None

class Gen(object):
    def records(self, cls):
        for i in range(3):
            setattr(cls, "id", "%s%s" % (cls.__doc__,  i))
            yield cls

    def display(self, rec):
        for i in rec.__dict__.keys():
            if not i.startswith("_"):
                print "%s: %s: %s" % (rec.__doc__, i, rec.__dict__[i])

class GenA(Gen):
    def __init__(self):
        self.genB = GenB()
    
    def records(self):
        for a in Gen.records(self, A()):
            for b in self.genB.records():
                #self.genB.display(b)
                a.b.append(b)
            #self.display(a)
            yield a

class GenB(Gen):
    def records(self):
        return Gen.records(self, B())

# testing..

aRecs = []
bRecs = []

for i, r in enumerate(GenB().records()):
    bRecs.append(r)
    print i, r.id, r

for i, r in enumerate(GenA().records()):
    aRecs.append(r)
    print i, r.id, r
    for b in r.b:
        print b.id, b


Here's the commented output:
# even if I keep a reference to each rec, the object is reused:
0 B0 <__main__.B object at 0xb7bd0f8c>
1 B1 <__main__.B object at 0xb7bd0f8c>
2 B2 <__main__.B object at 0xb7bd0f8c>
# same here, with additional quadratic behavior, I do not understand
0 A0 <__main__.A object at 0xb7bd206c>
B2 <__main__.B object at 0xb7bd210c>
B2 <__main__.B object at 0xb7bd210c>
B2 <__main__.B object at 0xb7bd210c>
1 A1 <__main__.A object at 0xb7bd206c>
B2 <__main__.B object at 0xb7bd210c>
B2 <__main__.B object at 0xb7bd210c>
B2 <__main__.B object at 0xb7bd210c>
B2 <__main__.B object at 0xb7bd20ec>
B2 <__main__.B object at 0xb7bd20ec>
B2 <__main__.B object at 0xb7bd20ec>
2 A2 <__main__.A object at 0xb7bd206c>
B2 <__main__.B object at 0xb7bd210c>
B2 <__main__.B object at 0xb7bd210c>
B2 <__main__.B object at 0xb7bd210c>
B2 <__main__.B object at 0xb7bd20ec>
B2 <__main__.B object at 0xb7bd20ec>
B2 <__main__.B object at 0xb7bd20ec>
B2 <__main__.B object at 0xb7bd0f8c>
B2 <__main__.B object at 0xb7bd0f8c>
B2 <__main__.B object at 0xb7bd0f8c>

I expected to get 3 different class objects from both sections, with each A
containing 3 different Bs in the latter section, but obviously got
something else. 

Could some kind soul help me to distangle my mind twist here? Am I healable?

TIA, Pete



More information about the Python-list mailing list