inconsistency with += between different types ?

Donn Cave donn at u.washington.edu
Wed Aug 7 20:56:29 CEST 2002


Quoth list-python at ccraig.org (Christopher A. Craig):
| "Donn Cave" <donn at u.washington.edu> writes:
|> The sad thing is, all this hand-waving is really germane to only one
|> issue I can think of, an object's suitability for use as a hash key.
|
| It is also relevant to a lot of things related to numbers.  All
| references to the same integer reference the same object.  This means
| that if integers were mutable then in theory the following result
| could occur (a result, which I'll note is similar to something that
| was actually possible in early versions of SmallTalk for reasons of
| mutability).

Old versions of FORTRAN got there first with this feature.  But
that's not what we're talking about, it isn't what mutable means
in Python.  In Python, assignment always does the same thing,
irrespective of the type of the LHS --   a = b  has no effect
on the object originally represented by a (except that that it's
subject to deletion if there are no other bindings), whether that
object is "mutable" or not.  Assignment-syntax functions like
__setitem__ and __setattr__ can do what they want, but they normally
and naturally tend to inherit the same binding semantics from the
collection primitives they're operating on, like the class instance
dictionary or an internal list.

What we mean by ``mutable'' pretty much boils down to ``has some
place inside to (re)bind values.''  An integer has no such place,
consequently supports no mutations, so it's a simply immutable.
A list supports mutations through setitem et al., so it's simply
mutable.  What about a file object, is it mutable?

How about a class instance that does the best it can to be
immutable?  Say I get tired of the tuple of 10 integers posix.stat()
returns, and I write a class that acts like struct stat ...

  class A:
      def __init__(self, st):
          self.__dict__['value'] = st
          i = 0
          for n in ('mode', 'ino', 'dev', 'nlink', 'uid', 'gid', 'size',
                    'atime', 'mtime', 'ctime'):
              self.__dict__[n] = st[i]
              i = i + 1
      def __getitem__(self, i):
          return self.value[i]
      def __setitem__(self, i, v):
          raise TypeError, 'hey, I\'m like a tuple'
      def __setattr__(self, a, v):
          raise TypeError, 'hey, I\'m like a tuple'

Is it mutable?  You can crawl through the back window and modify
__dict__, but in its intended application it's immutable.  Who cares?
The person who has to decide if it's a valid hash key, no one else.
Mutability is generally not a real issue, per se.

Getting back a little towards the original subject, Andreas Leitgeb's
proposal wouldn't affect lists, integers etc.  Only class instances
that define __iadd__ etc., and wouldn't really affect many of them.
It would make in-place operations easier to document, by artificially
constraining their behavior so that all class instances modify in place.
Of course that would be wrong for a class like the one above that wants
to be immutable in application -- some kind of number, for example.

	Donn Cave, donn at u.washington.edu



More information about the Python-list mailing list