[Discuss] A question for the Python gurus

Deryk Barker dbarker at camosun.bc.ca
Fri Jul 28 20:41:55 PDT 2006


Adam Parkin wrote:

> Continuing with my "question for the ..... gurus" series of e-mails 
> (hehe)....
>
> Due to all the recommendations I've been getting lately about the 
> language I've decided to give Python a pretty good whirl, but I have a 
> question in regards to function calling semantics.
>
> It's my understanding that everything in Python is passed by value, 
> but in every case that value is an object reference (much like when 
> you pass an object to a method in Java).  

Indeed, but this is really call by reference.

> It's also my understanding that as a result of this any modifications 
> to an argument passed into a function will be seen outside of the 
> function.  

No - because assignment in python is also by reference:

def   test (x):

    x = x * 2

z = 5
print z      # prints 5
test (z)     # pass z to test
print z      # prints 5

the reason is the assignment by reference:

    x = someexpression

simply means that the name x now refers to the value of that expression. 
When we call test in the code above, the local parameter is indeed bound 
to the same physical storage as z. However, the assignment will:

    calculate x * 2
    put the calculated value in memory
    make x refer to this *new* data storage


The classic example in most languages is swap, can we write a swap 
function/procedure/subroutine/method which will exchange its parameters?

In C we can, but only by explicitly passing pointers, as all calls are 
by value in C (which means copying). In Pascal,Modula-2,PL/1,C++ we can 
tell the compiler that a parameter should be passed by reference. IN 
this languages assignment is by copying, not by reference, hence the 
swap function can be written.

In python it can't.

However, you can easily write:

    x,y = y, x


> And finally, it's also my understanding that strings are immutable 
> objects.  So combining those facts together, it seems to me that 
> there's no way to write a function in Python which takes a string as 
> an argument and modifies that string in place.  Is this correct?  Like 
> say I wanted to write a Python equivalent to Perl's chomp function, I 
> might try something like:
>
> def chomp (string):
>     string = string.rstrip('\n')
>
> but of course this doesn't work, as rstrip creates a new string 
> reference which we are assigning to "string" and of course since 
> references are passed by value the change isn't seen outside of the 
> function.  Any way around this?

It's correct, but not because of the way arguments are passed. Arrays 
are mutable and if you pass an array to a function the array contents 
can be changed:

def testa (A):
    A[0] = A[0] * 2

X = [1,2,3,4]
print X   # prints [1,2,3,4]
testa (X)
print X   # prints [2,2,3,4]

this does not work for strings, because - as you rightly say, strings 
are immutable.

Why not simply return the new string?



More information about the Discuss mailing list