"pass by reference?"

Bengt Richter bokr at oz.net
Sun Feb 24 05:01:18 CET 2002


On Sat, 23 Feb 2002 15:34:01 +0700, Tripp Scott <tripps81 at yahoo.com> wrote:

>Suppose I want to make a function that modifies its argument:
>
>  a = -1
>  make_abs(a)
>  print a # = 1
>
>What is the Pythonic way of doing this? Wrap it in a list?
>
>  make_abs([a])
>
Well, if you really want to[**], I think you might want to use
the list wrapper a little differently:

 >>> a = [-1]
 >>> def make_abs(x):
 ...     x[0] = abs(x[0])
 ...
 >>> a
 [-1]
 >>> make_abs(a)
 >>> a
 [1]

but be careful how you bind to mutable things, as all bindings
to the same thing will show a change to the thing bound to:

 >>> a = b = [-1]
 >>> a
 [-1]
 >>> b
 [-1]
 >>> make_abs(a)
 >>> a
 [1]
 >>> b
 [1]

note the different result here:

 >>> a = [-1]
 >>> b = [-1]
 >>> a
 [-1]
 >>> b
 [-1]
 >>> make_abs(a)
 >>> a
 [1]
 >>> b
 [-1]

You can also define your own mutable object with a class,
as mentioned elsewhere.

USING A CLASS IS PROBABLY A BETTER IDEA <<<< [**]notice ;-)

a=A(-1) and a.v = -1 or a.setval(-1) are probably less misleading than
a[0] = -1 or a = [-1].

Though it might be nice Python had an object update operator, so you
wouldn't have to know method or attribute names to do a default
state update operation. E.g. (using a ':=' token for the operator),

a := -1  #read as 'a updated with -1'

could translate to a.__update__(-1), which you could define
or override as desired. Incidentally, this could be an expression
evaluating to a reference to the updated object by returning self
from the method, so it could be used flexibly.

Though it introduces ambiguities, I sometimes think I'd like
to be able to define a __getval__ method that would be called
by a simple reference to the object in an expression. E.g.,

x = y

might become x = y.__getval__() so instead of x binding to the
y object instance, it would get whatever y was defined to deliver
as a default value. It would mean that you couldn't bind to y
as an object, unless __getval__() returned self, or you provided
another method to do that, as in z = y.it_self() or such.

With __getval__, x.y and x .y would probably mean different things.
I.e., x.__getattr__('y') vs x.__getval__().__getattr__('y')

It could obviously be abused, but could be useful too.

Regards,
Bengt Richter




More information about the Python-list mailing list