trouble with generators

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


Hi Diez,

first, thanks for your comprehensive answer.

Diez B. Roggisch wrote:

> Hans-Peter Jansen schrieb:
>> 
>> I'm trying to generate a bunch of similar classes, where some are
>> contained in list attributes of others, e.g.:
> 
> All your code below shows that you don't create classes, but _instances_
> of classes. So - is that what you mean to do? 

Yes, exactly. Sorry for the confusion..

> 
> In a nutshell, you do this:
> 
> b = B()
> res = []
> for i in xrange(3):
>     b.id = i
>     res.append(b)
> 
> Always the same b.
> 
> What you seem to want is this
> 
>  >>> class B(object):
> ...    pass
> ...
>  >>> res = []
>  >>> for i in xrange(3):
> ...     class BSubClass(B):
> ...          pass
> ...     BSubClass.id = i
> ...     res.append(BSubClass)
> ...
>  >>> print [c.id for c in res]
> [0, 1, 2]
> 
> I'm still not sure what you want - do you want instances created, or
> classes? For the former, you need constructor calls on your classes, and
> pass the class instead of an instance. Like this:
> 
> 
> class B(object):
>     pass
> 
> 
> def g(cls):
>      for i in xrange(3):
>          o = cls()
>          o.id = i
>          yield o
> 
> list(g(B))
 
Yes, that did the trick. Silly me. Rookie error. Here's what I was after:

#!/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):
    "Gen"
    def records(self, cls):
        for n in range(3):
            i = cls()
            i.id = "%s%s" % (i.__doc__,  n)
            yield 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():
                a.b.append(b)
            yield a

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

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

created pretty nice different _instances_ of what I wanted:
0 B0 <__main__.B object at 0xb7cacfec>
1 B1 <__main__.B object at 0xb7cae04c>
2 B2 <__main__.B object at 0xb7cae08c>

0 A0 <__main__.A object at 0xb7cae12c>
B0 <__main__.B object at 0xb7cae1ac>
B1 <__main__.B object at 0xb7cae1ec>
B2 <__main__.B object at 0xb7cae22c>
1 A1 <__main__.A object at 0xb7cae16c>
B0 <__main__.B object at 0xb7cae2ac>
B1 <__main__.B object at 0xb7cae2ec>
B2 <__main__.B object at 0xb7cae32c>
2 A2 <__main__.A object at 0xb7cae26c>
B0 <__main__.B object at 0xb7cae3ac>
B1 <__main__.B object at 0xb7cae3ec>
B2 <__main__.B object at 0xb7cae42c>

Didn't found the forest because all the trees. Thanks again.

Greetings to Berlin,
        Pete



More information about the Python-list mailing list