newbie questions

Nick Coghlan ncoghlan at iinet.net.au
Mon Dec 13 13:16:02 CET 2004


"houbahop <d.lapasset"@bag.python.org wrote:
> Thank you everyone, but I still not understand why such a comon feature like 
> passing parameters byref that is present in most serious programming
> languages is not possible in a clean way,here in python.
> 
> I have the habit to never use globals as far as possible and this involve 
> that my main function is passing some parameters by reference to subs to 
> allow them to modify the vars.

Python could be said to pass everything by reference. You are getting caught 
more by the difference between mutable and immutable types, than by the 
distinction between 'pass by reference' and 'pass by value' that other languages 
have (Python actually uses a blend of the two ideas - you get references passed 
in, but it you use assignment on your arguments, the caller is not affected).

Items which are immutable can't be modified *at all* (not just in subroutines). 
The only thing you can do is take the name that references them and make them 
point to something else. Items which are mutable can be both modified and made 
to point to something else.

A list is mutable:

.>>>L = L1 = [1, 2, 3]
.>>>L is L1
True
.>>>L += [4]
.>>>L is L1  # Modification leaves us referencing the same thing
True
.>>> print L, L1
[1, 2, 3, 4] [1, 2, 3, 4]
.>>> L = []
.>>> L is L1  # Assignment gives a reference to a different thing
False
.>>> print L, L1
[] [1, 2, 3, 4]

A string is not:

.>>>S = S1 = "123"
.>>>S is S1
True
.>>>S += "4"  # Even modification gives a reference to a different thing
.>>>S is S1
False
.>>>print S, S1
"1234", "123"

> I would be sad to break my structured programming scheme because a lack of 
> feature.

As you work with Python, you'll find a lot of the heavy lifting is done with 
mutable types (particularly list and dict). For these, modification within a 
function is quite straightforward (just modify the argument directly - e.g. by 
adding items to a list or dictionary).

Immutable types (e.g. strings, numbers, tuples) are generally returned directly 
from functions, rather than returned as 'output parameters'. The ability to 
return multiple values easily (via "return a, b, c" & "x, y, z = myfunc()" 
generally eliminates the need for 'by reference' output parameters as used by C, 
C++, Java and the like.

Regards,
Nick.

P.S. If you *really*, *really*, *really* want to fake output parameters, just 
wrap them in a list:

def myfunc(outputparam):
   # Do something
   outputparam[0] = result

x = []    # Like declaring x as a pointer to something
myfunc(x) # The function fills the 'pointer'
x = x[0]  # We dereference our 'pointer'

There's generally a better way, though (which way that is depends greatly on the 
context).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at email.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://boredomandlaziness.skystorm.net



More information about the Python-list mailing list