houbahop <d.lapasset"@bag.python.org said:
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.