[Tutor] Pass by reference

ibraheem umaru-mohammed ium@micromuse.com
Wed, 11 Jul 2001 18:42:08 +0100


[ibraheem umaru-mohammed wrote...]
-| [Praveen Pathiyil wrote...]
-| -| Can we do a "pass by reference" in python ?
-| 
-| no. not directly.
-| 
-| -| Ex:
-| -| 
-| -| ( I would like to know whether there is a way to have the modified ex_dict to be visible in modified form in func1 with out explicitly returning that )
-| -| 
-| -| def func2(x, ex_dict):
-| -|     ex_dict[x] = x*x
-| -| 
-| -| def func1(a):
-| -|     ex_dict = {}
-| -|     func2(a, ex_dict)
-| -| 
-| -| func1(2)
-| -| 
-| 
-| You can do this in at least two ways: 
-| 	o using a class
-| 	o using global dictionary variable
-| 

This is actually in the FAQ - so here is the answer in full ;)

<snip>

4.35. How do I write a function with output parameters (call by reference)?

[Mark Lutz] The thing to remember is that arguments are passed by assignment
in Python. Since assignment just creates references to objects, there's no
alias between an argument name in the caller and callee, and so no
call-by-reference per se. But you can simulate it in a number of ways:

1) By using global variables; but you probably shouldn't :-)

2) By passing a mutable (changeable in-place) object:

      def func1(a):
          a[0] = 'new-value'     # 'a' references a mutable list
          a[1] = a[1] + 1        # changes a shared object

      args = ['old-value', 99]
      func1(args)
      print args[0], args[1]     # output: new-value 100

3) By returning a tuple, holding the final values of arguments:

      def func2(a, b):
          a = 'new-value'        # a and b are local names
          b = b + 1              # assigned to new objects
          return a, b            # return new values

      x, y = 'old-value', 99
      x, y = func2(x, y)
      print x, y                 # output: new-value 100

4) And other ideas that fall-out from Python's object model. For instance,
it might be clearer to pass in a mutable dictionary:

      def func3(args):
          args['a'] = 'new-value'     # args is a mutable dictionary
          args['b'] = args['b'] + 1   # change it in-place

      args = {'a':' old-value', 'b': 99}
      func3(args)
      print args['a'], args['b']

5) Or bundle-up values in a class instance:

      class callByRef:
          def __init__(self, **args):
              for (key, value) in args.items():
                  setattr(self, key, value)

      def func4(args):
          args.a = 'new-value'        # args is a mutable callByRef
          args.b = args.b + 1         # change object in-place

      args = callByRef(a='old-value', b=99)
      func4(args)
      print args.a, args.b

   But there's probably no good reason to get this complicated :-).

[Python's author favors solution 3 in most cases.]

<snip>

Kindest regards,

			--ibs.
-- 
Do not take life too seriously; you will never get out of it alive.