Making immutable instances

Mike vimakefile at yahoo.com
Thu Nov 24 11:26:12 EST 2005


"Giovanni Bajo" <noway at sorry.com> wrote in message 
news:bqehf.3897$S6.66671 at twister2.libero.it...
> Mike wrote:
>
>>> How can a (user-defined) class ensure that its instances are
>>> immutable, like an int or a tuple, without inheriting from those
>>> types?
>>>
>>> What caveats should be observed in making immutable instances?
>>
>> IMHO, this is usually (but not always) a mistake. (If you're
>> programming a missle guidance system, or it makes your program go
>> faster it's not a mistake :))
>> So are PRIVATE, CONST (all types), SEALED, FINAL, etc -- even the best
>> programmer doesn't foresee what a user will want to do to make best
>> use of his components, and many a time I've been annoyed (in Java and
>> MS frameworks) by not being able to access/modify/subclass a
>> member/class that I know is there because it has to be there (or
>> because I can see it in the debugger), but it's not accessable
>> because the programmer was overly clever and had been to OOP school.

> There's a big difference. An immutable object has a totally different 
> semantic,
> compared to a mutable object. If you document it to be immutable, and 
> maybe
> even provide __eq__ /__hash__, adding attributes from it is surely an user 
> bug.
> And surely a bug for which I'd expect an exception to be raised.

Why is it "surely" a bug?  It is arguable whether adding new attributes (vs. 
changing those that are already there) is, in fact, mutation.
How will adding user attibutes that your code knows nothing about break the 
contracts you have specified?
If __hash__/__eq__ does not look at the new attributes, all the better - as 
these attributes are just "along for the ride". (But if the hash reflected 
into all attrs, things would indeed break.)
Personally, adding attributes to existing objects would not be my preferred 
programming style, epsecailly in a langauge like Python with rich and 
easy-to-use associative data structures, but sometimes it's the quickest or 
only way to get something done -- if you are unwilling (or more likely, 
unable) to modify all the levels of method signatures required to pass new 
information about an object/state along.
I can see how a compile-time *warning* would be of value to show it is not 
the *desired* usage pattern in the eyes of the component programmer, but 
beyond that, why get in the way? Python is not Java or any other language --  
sometimes I don't like the total dynamicity either (I'd like optional types 
and/or type-inference), but it is what it is.

> Sometimes, I play with some of my objects and I have to go back and check
> documentation whether they are immutable or not, to make sure I use the 
> correct
> usage pattern. That's fine, this is what docs are for, but couldn't Python 
> give
> me some way to enforce this so that, if I or some other dev do the 
> mistake, it
> doesn't go unnoticed?

It sounds like what you may want are opaque objects where you can control 
access better -- if that's so, keep them all hidden, and just pass back a 
handle or proxy - you could always implement restrictred/readonly or 
copy-on-write semantics. (If there isn't one already, auto-proxy generation 
for this sort of thing sounds like a fun python cookbook recipe...)

> -- 
> Giovanni Bajo







More information about the Python-list mailing list