newbie questions

Steven Bethard steven.bethard at gmail.com
Sat Dec 11 20:27:21 CET 2004


houbahop wrote:
> Passing a pointer by value appears to me as passing a var by reference.

Well, at least in the PL literature, there's a subtle difference.  If 
Python supported pass-by-reference, you could do something like:

 >>> def clear(byref lst):
...     lst = []
...
 >>> x = [pow(x, 11, 17) for x in range(10)]
 >>> clear(x)
 >>> x
[]

Passing a variable by reference means that the *variable* in the 
function is the same *variable* as outside the function.  Notice that 
this is not the same thing as saying that the variable in the function 
is a pointer to the same object as the variable outside the function.

Python doesn't support pass-by-reference in this standard use of the 
term.  But Python is basically *only* passing pointers around; there is 
no way to do anything else.  So if passing a pointer by value is 
sufficient for your purposes then you won't have any problems with 
Python, because this is what it always does. =)

> Thanks I will try all of that, but what does really means mutating in 
> python? It's the first time I hear this word in programming :))

The term is used most commonly in the pair accessor/mutator, also known 
as getter/setter.  In general, a mutator is just a method of an object 
that changes that object's state.  In Python, assignment does not invoke 
a method of an object; it binds a name to an object.  For this reason, 
code like:

def clear(lst):
     lst = [] # binds the name lst to a new value, []
              # ignoring previous value

will not change the list because it is not calling methods of the list 
object to change it.  It will instead rebind the local name "lst" to a 
new object, [].  This does not change the previous object that was 
associated with "lst" and so if you have another variable bound to the 
previous value ("x" in my examples), it will still retain the old, 
unchanged object.

So, while assignment does not invoke a method of an object, many other 
things in Python do, and all of these things will appropriately modify 
the state of the object.  For example:

def clear(lst):
     lst[:] = [] # implicitly calls the setter/mutator list.__setslice__

def clear(lst):
     while lst:     # implicitly calls the getter/accessor len(lst)
         lst.pop() # explicit call to setter/mutator list.pop

# don't use this; it's inefficient, I'm just using it as an example
# of using a different setter/mutator
def clear(lst):
     while lst:    # implicitly calls the getter/accessor len(lst)
         last_item = lst[-1]   # implicitly calls the getter/accessor
                               # list.__getitem__
         lst.remove(last_item) # explicitly calls setter/mutator
                               # list.remove

Note that all of these functions will successfully clear the list 
because they mutate the object itself, instead of simply rebinding a 
name that at one point had been associated with the object.

HTH,

STeve



More information about the Python-list mailing list