Generating Multiple Class Instances

Alex Martelli aleaxit at yahoo.com
Wed Jun 6 23:33:56 CEST 2001


"Julie Torborg" <jtorborg at fnal.gov> wrote in message
news:3B1E9271.B05CC4E3 at fnal.gov...
> I'm no wiz at OOP, but I have the following problem:
>
> I have a list of some hundreds of items, each of which has several
> attributes,What I want to do is peg each of the values to the list item
> and move it around my program.  This seems like the perfect opportunity
> to take advantage of the OOP aspect of Python by setting up a class, but

Maybe.  If the attributes are a simple tuple, tuples may be simpler
and thus better than classes for your purpose.  Anyway...

> I can't create or use instances without hard-wiring it for every list
> item.  What I want to do is:
>
> class Quark:
>     def __init__(self):
>         self.color=getcolor()
>         self.mass=getmass()
>
> flavor=['up', 'down', 'strange', 'charm', 'top', 'bottom']
> for each in flavor:
>     each=Quark()

You want to *rebind* a loop variable in the loop body?  You can,
but of course it will be bound again on the very next leg of the
loop -- so it's a pretty futile exercise.

Maybe you want to use string 'each' as the name of an attribute
of some object?  Then it's easy:

class Buncho: pass
bunch=Buncho()
for each in flavor:
    setattr(bunch, flavor, Quark())

though I'm not surer how getcolor() and getmass() are
supposed to get their values -- are you SURE you don't
mean something like:

class Quark:
    def __init__(self, name):
        self.color=getcolor(name)
        self.mass=getmass(name)
        # and maybe
        self.name = name
?
In this case the for body would be:
    setattr(bunch, flavor, Quark(flavor))

But anyway I'm not clear how this generalizes to HUNDREDS
of items... still, it would work, though how you'd get your
item names I don't know.


> ###Then later:
> for each in flavor:
>     print each.color

In the above approach it would be
for each in flavor:
    print getattr(bunch,each).color

Of course it *WOULD* be marginally neater to have instead:
bunch={}
and instead of the setattr and getattr you would have
    bunch[flavor] = Quark(flavor)
and
    print bunch[flavor].color
but if you do want bunch to be an instance object instead
of a dictionary, it ain't hard, just a bit less convenient.

Or maybe you want a list...:

for ieach in range(len(flavor)):
    flavor[ieach] = Quark(flavor[ieach])

and then later:

for each in flavor
    print each.color

WOULD work.  Personally, I'd far prefer this one, btw.


> ###What I'm relegated to doing is:
>
> up=Quark()
> down=Quark()
> strange=Quark()...
>
> print up.color
> print down.color
> print strange.color...

I'm still unsure about how the getcolor() and getmass() global
functions are supposed to guess at the quark's characteristics
without getting the quark name as an argument, of course.

But anyway, local variables are the least appropriate ways to
keep so many things with systematic names, of course.  List
items, dictionary items, instance attributes (basically just
syntax sugar for dictionary items), are all better here.


> Which works, but with hundreds of list items, gets messy in a hurry.
> I've also tried messing around with using something that looks more like
> quark=Quark() several times, but then all the info stored in the
> previous instance gets obliterated.  I've also tried using lists and
> dictionaries, but they're bulky

In what sense?  In the above examples the suggestions I give
to use dictionaries and lists of instances seem quite un-bulky.

> and what's the point of using an OOP
> language if there's no additional functionality or elegance?

You have a multi-paradigm language at hand, you must learn
to use the right construct for each job.  Each Quark object is
quite well modeled as an instance object, apparently, but the
issue is, where do we keep the references to those instances.
Not in local variables of course -- that's got nothing to do
with OOP!-).  Another separate instance with the only role
of bunching up the quarks can work, as I've shown, but IMHO
is not optimal.  Containers (lists and dictionaries) are good
ways to contain stuff (here, e.g., contain instances, if you do
want to model each Quark by an instance, which might well
be optimal, depending).  You may want to write your own
containers by OOP, but often using the existing ones is going
to be best, they're simple and speedy (anything BUT bulky!-).


Alex






More information about the Python-list mailing list