two quick questions

Chad Netzer cnetzer at sonic.net
Wed Aug 13 03:40:41 EDT 2003


On Tue, 2003-08-12 at 23:06, Elaine Jackson wrote:

> 1) Does Python have passing-by-reference?

Yes.  But the references you are passing are references to objects (not
memory locations), and objects themselves can be changeable (mutable) or
not.  When you pass objects, copies are not automatically made (so
assignment is very speedy).

I prefer to say that these concepts should be put aside when thinking
about python.

Python has names that refer to objects.  Objects are created, and can be
assigned one or more names (using assignment).  Some objects can mutate
(like objects made by user defined classes), some cannot (like strings
or integers).

When you supply function arguments, copies of the object are not
automatically made.  If you pass a mutable object, the callee has a name
for that (actual) object, and can mutate it.  If you pass an immutable
object, they cannot.

When you use assignment, a copy of the object is not made.  It simply
gets another name that refers to it.

Globals can confuse the issue, since they allow you to change the names
used in the global scope (ie. they can allow your function to modify a
non-local namespace, rather than just the objects passed in to the local
namespace.

Examples:

1)  Without using globals:

a = 1    # Create the immutable 1 integer object and name it 'a'
b = []   # Create a mutable list

def f( c, d ):
   c = 3              # Reassign name 'c' to the 3 integer object
   d.append( "foo" )  # modify the list that is named 'd'

f( a, b )    # Copies of 'a', and 'b' are NOT made.
             # when you call f(), c is a, and d is b.
             # ie. The names in the function refer to the same
             # objects as the (different) names outside the function

a == 1
b == ['foo']

Discussion:
 The f() function changed 'b' because the object itself was changeable. 
The a object is still 1, because the 1 object cannot
be changed at all, and f() couldn't reassign a because it gets a name
that refers to the object, not access to the namespace itself.


2) similar example using globals to pervert namespace

a = 1

def g():
   global a   # This says that 'a' refers to the global 'a' name
   a = 2      # Since I have access to the name 'a', I can change
              # the object that the global 'a' refers to.

g()
a == 2        # After calling g, the global name 'a' was changed.


The point of the globals example, was that it can be used to confuse
your understanding.  So ignore it for now, and think of objects as
free-standing entities that can have multiple names, in multiple scopes,
it is easier to understand that you are passing around access to those
objects, and you can manipulate them if they are mutable.  But,
pass-by-value and pass-by-reference, at least as they are typically
discussed in the 'C' programming world, are less applicable concepts.

As you get more advanced, you will see that Python uses dictionaries to
hold namespaces, and you can pass thos dictionaries (and thus the
namespaces) around as well.


> 2) In ordinary parlance, "deep" implies "shallow" but not conversely. In the
> Python "copy" module (if I understand correctly), the implication goes the other
> way. Do you find this a nuisance?

Not sure what you mean.

-- 
Chad Netzer






More information about the Python-list mailing list