reference or pointer to some object?

Jeff Shannon jeff at
Thu Jan 13 16:03:09 EST 2005

Torsten Mohr wrote:

> But i think my understanding was wrong (though it is not yet
> clear).  If i hand over a large string to a function and the
> function had the possibility to change it, wouldn't that mean
> that it is necessary to hand over a _copy_ of the string?
> Else, how could it be immutable?

Anything which might change the string, can only do so by returning a 
*new* string.

 >>> a = "My first string"
 >>> b = a.replace('first', 'second')
 >>> b
'My second string'
 >>> a
'My first string'

Saying that strings are immutable means that, when 'a' is pointing to 
a string, the (string) object that 'a' points to will always be the 
same.  (Unless 'a' is re-bound, or someone uses some deep black magic 
to change things "behind the scenes"...)  No method that I call on 
'a', or function that I pass 'a' to, can alter that object -- it can 
only create a new object based off of the original.  (You can 
demonstrate this by checking the id() of the objects.)

Mutable objects, on the other hand, can change in place.  In the case 
of lists, for example, it will stay the same list object, but the list 
contents can change.

Note, also, that passing a string into a function does not copy the 
string; it creates a new name binding (i.e. reference) to the same object.

 >>> def func(item):
... 	print "Initial ID:", id(item)
... 	item = item.replace('first', 'second')
... 	print "Resulting ID:", id(item)
 >>> id(a)
 >>> func(a)
Initial ID: 26278416
Resulting ID: 26322672
 >>> id(a)

> Thinking about all this i came to the idea "How would i write
> a function that changes a string with not much overhead?".

Since strings cannot really be changed, you simply try to minimize the 
number of new strings created.  For example, appending to a string 
inside of a for-loop creates a new string object each time, so it's 
generally more efficient to convert the string to a list, append to 
the list (which doesn't create a new object), and then join the list 
together into a string.

> def func(s):
>   change s in some way, remove all newlines, replace some
>     charaters by others, ...
>   return s
> s = func(s)
> This seems to be a way to go, but it becomes messy if i hand over
> lots of parameters and expect some more return functions.

This has the advantage of being explicit about s being (potentially) 
changed.  References, in the way that you mean them, are even messier 
in the case of numerous parameters because *any* of those parameters 
might change.  By simply returning (new) objects for all changes, the 
function makes it very clear what's affected and what isn't.

Jeff Shannon
Credit International

More information about the Python-list mailing list