When is it a pointer (aka reference) - when is it a copy?

George Sakkis george.sakkis at gmail.com
Wed Sep 13 22:07:46 EDT 2006


Grant Edwards wrote:
> On 2006-09-13, John Henry <john106henry at hotmail.com> wrote:

> > So, if I understand you correctly, I must make the reference
> > to a more elaborate representation.  Like:
> >
> >    i=[1,]
> >    j=i
> >    j[0]=2
> >    print i
> >
> > in order to get 2 printed.
> >
> > Correct?
>
> I suppose, for some values of "correct".  You've bound the
> names "i" and "j" to the same mutable object, then mutated that
> object.  Afterwards "i" and "i" still refer to that mutated
> object.

Another way to explain why this is so, without fuzzy terms like "a more
elaborate representation", is that although the statements "x = 2" and
"x[0] = 2" look both as "assignments" syntactically, they work quite
differently under the hood. The former binds a name ("x") to an object
("2"). The latter is syntactic sugar for a method call:
x.__setitem__(0,2). If x happens to be a list, this is equivalent to
calling the unbound method list.__setitem__(x,0,2) which, as you
already know, mutates the list x. The important thing to remember
though is that the effect of something like "x[0] = 2" depends on the
type of x. Any class can define a __setitem__(index,value) method with
arbitrary semantics; it is not (and cannot be) forced to mutate x. The
bottom line is that you can't tell in advance what "x[0] = 2" will do
without knowing the type of x. A binding OTOH like "x=2" has always the
same semantics: make the name "x" refer to the object "2".

Similarly to "x[0] = 2", something like "x.foo = 2" looks like an
assignment but it's again syntactic sugar for a (different) method
call: x.__setattr__('foo',2). All the above about __setitem__ hold for
__setattr__ too.


HTH,
George




More information about the Python-list mailing list