class constructors: class vs. instance defaults
Michael Hoffman
m.h.3.9.1.without.dots.at.cam.ac.uk at example.com
Wed Oct 6 18:51:43 EDT 2004
Erik Johnson <ej <at> wellkeeper wrote:
> You might be surprised to find out that all the Bar objects end up
> sharing the same foo_d dictionary.
I wasn't <wink> but I can see why one might not expect this. There was a
thread on this phenomenon this very week...
> I struggled with that for a
> while and eventually reasoned that the {} in the argument list to my
> constructor is executed at the time of class definition, and is essentially
> a reference to an instantiated dictionary object and therefor there is a
> little empty dictionary sitting in memory somewhere prior to me ever
> instantiating a Bar object. New Bar objects constructed without providing
> their own foo_d end up sharing that one. I think this makes sense enough,
> now (if I'm missing something, speak up).
That's exactly right.
> So, one work-around is to do this:
>
> #=======================================================================
> class Bar:
>
> def __init__(self, foo_d=None)
> if foo_d:
> self.foo_d = foo_d
> else:
> self.foo_d = {}
To be honest that is almost exactly what I would do. Except that I would
use "if foo_d is not None" because the truth value of an empty container
(such as {}) is False. So if someone specified an empty dict subclass or
a list as the foo_d, you would end up creating a new empty dict instead
for self.foo_d.
Maybe that is a little far-fetched, but you seem to want to start with
good habits (which is very commendable), and using "if x is not None"
when you want to test whether it is None or not is a good idea. :)
> Is there a better way to do this sort of thing, or is that
> perfectly reasonable code?
Looks reasonable enough to me.
--
Michael Hoffman
More information about the Python-list
mailing list