Scope rule pecularities

Josiah Carlson jcarlson at uci.edu
Thu May 20 01:12:32 EDT 2004


>>As you mentioned later, in C, you can use *a = 1 to modify a single
>>instance of 'a'.  However, immutables in Python never do the *a = 1
>>assignment.  Mutables do so,
> 
> I am not sure what you mean to say that mutables 'do the *a=1 assignment'.
> This does not strike me as a useful viewpoint for understanding Python.

If you read Antoon's post, he mentions that in C you can have multiple 
integer pointers pointing to the same memory location, and changing the 
contents of that one memory location (*a = 1) changes the "value" of 
other names.

As you state, since Python only ever rebinds names on assignments, the 
only even near equivalent would be using something like 'a[0] = 1' or 
even 'a.p = 1' (for some mutable mapping or settable attribute 
respectively), and claim that many names can all reference the same 'a'.

I agree it is not terribly useful for understanding Python, unless one 
has background with C or C++, which seems to be the case with Antoon.


>>which is why the final line of...
>>   m = n = []
> 
> At this point, m is n, not merely m == n.  Both names are bound to one and
> the same object.

Indeed, I should have used 'is'.


>>For immutables, on modification, a new instance of the immutable is
>>created, the value being set accordingly.
> 
> Since immutable objects cannot be modified, I am not sure what you are
> saying.  In any case,

What I should have said is "On any /attempted/ mutation of an immutable 
via the (+-/*|&^%)= (and any other that I have forgotten, if any) 
operators, a new object is created with the appropriate modifications, 
leaving all previously bound names bound to the original immutable, but 
changing the binding of the current name to the new immutable.  This is 
in stark contrast with a mutable mutation, which will modify and return 
the original object (via the __i***__ instance methods), leave all 
previously bound names bound to the mutable."



[snip good example]

>>Now that we've gotten to the point, __iadd__ and friends, we know we
>>disagree.  If you feel terribly strongly about it, post a bug report or
>>feature requrest to SF.
> 
> No, please do not burden the volunteer developers with false bug reports or
> useless feature requests.  The semantics of += and family were debated when
> added a few years ago and will not change for the foreseeable future.  Keep
> repeated debate and explanation of such things to c.l.p.

I had no problem with the semantics in the first place.  I was just 
offering a place where the poster could go and get a definitive "go 
home, the semantics are not changing".  Thank you for giving him the 
definitive answer here, saves someone some time on SF.


>> I would venture a guess that within a week it
>>will be closed with a message stating, "yeah, we like it the way it is".
> 
> Or it might hang around a couple of years while people focus on real
> problems.

Sorry about that.


> About dictionaries: keys must be hashable (have __hash__ method);
> mutability is not directly involved (and there is indeed no direct test for
> such).  It would have been possible to key dictionaries by object id, and
> one can do so for user classes with def __hash__(s): return id(s).  But for
> fairly obvious reasons, builtins are hashed and keyed by value.  Perhaps
> less obviously, this can be true even across types.
> 
[snip good example]

I agree, it also provides a very convenient method for looking up values 
in a dictionary when you no longer have access to the key originally 
used.  My favorite example of this is...

 >>> a = b = 1.0
 >>> a is b
True
 >>> d = {a:'hello'}
 >>> b = (b + 1) - 1
 >>> a is b
False
 >>> d[b]
'hello'

The problem with mutable keys for dictionaries is that the only real 
solution either involves keeping an 'immutable copy' of the original 
item for hash-by-value (which Antoon offers in another leaf of this 
thread), or keeping a pointer to the mutable key.  The first has various 
issues, an the second requires that you must have the original object 
itself in order to access the value again, which kind of defeats one of 
the functional reasons for a dictionary structure.

  - Josiah



More information about the Python-list mailing list