class constructors: class vs. instance defaults

Erik Johnson spam at nospam.org
Thu Oct 7 15:20:43 EDT 2004


"Steven Bethard" <steven.bethard at gmail.com> wrote in message
news:mailman.4519.1097171627.5135.python-list at python.org...
> Steve Holden <steve <at> holdenweb.com> writes:
> >
> > Of course that means that
> >
> > (foo_d is None) or {}
> >
> > works, giving you the best of both worlds.
>
> I don't think this does what the OP wants it to:

    Heh.... amazing how tricky things can get in only a few lines, eh?
Actually, I noticed that that wasn't really the same thing. Here's what one
of my constructors looked like from yesterday (essentially the form given by
exarkun):

    #-------------------------------------------------------------------
    def __init__(self, fields=None, tanks=None, pipes=None):
        "Constructor."

        WkSuper.__init__(self, fields)

        if tanks is None: tanks = {}
        self.tanks_d = tanks

        if pipes is None: pipes = {}
        self.pipes_d = pipes

    #-------------------------------------------------------------------

    This sort of a "two and a half liner" is not as beautiful as the
one-line 'or' statement (which I had put in there at first) but after
thinking about it for a while, I decided that it's not a totally
unreasonable thing to pass your own empty dictionary and then expect to have
your object use that and not it's own.  I considered just ignoring that
issue and keeping in the back of my mind that if you passed an empty
dictionary it wasn't going to do what you probably expected, as exarkun
pointed out...

>  One could argue that there is something slightly wrong with both of
these.  Consider:
>
>  d = {}
>  b = Bar(d)
>    d['x'] = 'y'
>
>  One might reasonably expect b.foo_d['x'] to be 'y'.  In the case of the
above, it will not be; a KeyError will be raised instead.


    I eventually decided that ignoring the issue was not in the spirit of
that which I originally launched this post. These are all interesting issues
for a beginner, and I think I have become sharper at Python for having gone
through this. After thinking about this even more carefully today, a couple
of things come to mind:

    1) Might it make sense for Python to have both a mutable and an
immutable version of a dictionary?

    2) In terms of my own design and usage, I think the idea is that I'm
trying to make it convenient to pre-populate an object from a dictionary a
caller already has handy (which is probably me). I think I should probably
be doing a dictionary copy, not assignment. The passed dictionary is an
OBJECT INITIALZER. That is, once you've created the object, that's the place
to keep and manage your data - either through the object's exposed interface
(methods), or by directly setting member data fields. If you later muck
about with the dictionary from which the object was created, it probably
should NOT affect the object. (Granted, Python allows you to arrange to have
it work that way, which is cool, and other authors may have good reason to
do it that way, I think that is NOT the paradigm I want to encourage.)

    So, these are rather subtle issues that were not crystal clear to me
yesterday morning. I thank you all for the helpful and enlightening
discussion. I feel much better than when I thought my interpreter was broken
because all my objects had the same dictionary! :)

-ej





More information about the Python-list mailing list