[Python-Dev] How to suppress instance __dict__?
David Abrahams
dave@boost-consulting.com
Sun, 23 Mar 2003 09:48:53 -0500
Guido van Rossum <guido@python.org> writes:
>> I am generating extension types derived from a type which is derived
>> from int 'int' by calling the metaclass; in order to prevent instances
>> of the most-derived type from getting an instance __dict__ I am
>> putting an empty tuple in the class __dict__ as '__slots__'. The
>> problem with this hack is that it disables pickling of these babies:
>>
>> "a class that defines __slots__ without defining __getstate__
>> cannot be pickled"
>>
>> Yes, I can define __getstate__, __setstate__, and __getinitargs__ (the
>> only one that can actually do any work, since ints are immutable),
>> but I was wondering if there's a more straightforward way to suppress
>> the instance __dict__ in the derived classes.
>
> Actually, even __getinitargs__ won't work, because __init__ is called
> after the object is created.
...and ints are immutable. Right.
> In Python 2.3, you'd use __getnewargs__,
Cute.
It's almost too bad that the distinction between __new__ and __init__
is there -- as we find we need to legitimize the use of __new__ with
things like __getnewargs__ it be comes a little less clear which one
should be used, and when. TIMTOWDI and all that.
In the absence of clear guidelines I'm tempted to suggest that C++ got
this part right. Occasionally we get people who think they want to
call overridden virtual functions from constructors (I presume the
analogous thing could be done safely from __init__ but not from
__new__) but that's pretty rare. I'm interested in gaining insight
into the Pythonic thinking behind __new__/__init__; I'm sure I don't
have the complete picture.
> but I expect you're still bound to supporting Python 2.2
Yup, I think it would be bad to force my users to move to an
unreleased Python version at this point ;-)
> (Python 2.3 also doesn't have the error message above when
> pickling).
Nice. Too bad about 2.2.
> I think you could subclass the metaclass, override __new__, and delete
> the bogus __getstate__ from the type's __dict__. Then you'll get the
> default pickling behavior which ignores slots; that should work just
> fine in your case. :-)
Ooh, that's sneaky! But I can't quite see how it works. The error
message I quoted at the top about __getstate__ happens when you try to
pickle an instance of the class. If I delete __getstate__ during
__new__, it won't be there for pickle to find when I try to do the
pickling. What will keep it from inducing the same error?
Thanks,
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com