[Tutor] Confused about functions

Andrei Kulakov ak@silmarill.org
Thu, 01 Nov 2001 09:47:05 -0500


On Thu, Nov 01, 2001 at 02:08:51AM -0600, Kit O'Connell wrote:
> I am working my way through Learning Python (from O'Reilly). I am reading
> about functions and how they interact with variables (on built-in, global,
> and local levels). The following example code is given:
> 
> def changer (x,y):
> 	x = 2
> 	y[0] = 'spam'
> 
> X = 1
> L = [1, 2]
> changer (X, L)
> 
> at the end of the code, the value of X remains 1, because x is only set to
> 2 on a local level within the function. However, L has chaned to ['spam',
> 2].
> 
> I am confused. Why does L change, but X doesn't? I hope someone can
> explain this for me a bit.

Consider this:

def changer(x, y):
    x = 1
    y = [1,2]

X = 2
Y = [3,4]
changer(X, Y)
print X, Y # prints 2, [3,4]

Parts of lists can be changed, on the fly. In your code, that's precisely 
what you do. Lists can often be quite large (millions of items) and you
often want to change just one item (or a few) of that list, instead of
making a copy. Imagine how much more expensive it'd be to make a new copy
of a million-item list and change stuff in the new copy, and keep the old
one unchanged!

Now you're probably thinking, well, why doesn't the integer here behave
consistently with a list, then? The reason is encapsulation of data -
in a solid program, you want to pass some stuff into a function and get
results. For instance:

def mult(x, y):
  return x * y

Now, if you're thinking at the place in the code where you call this
function, you'll see this:

result = mult(val1, val2)

You shouldn't need to look at the function to be sure that val1 and val2
don't change. If mult changed val1, for instance, that'd be bad because
when you look at the line above, it looks like you just pass two values
in and get a result. This makes for a much more clearer program: if you
look through code and try to figure out the flow of logic, you don't have
to constantly jump to that functions code to check whether it modified
a variable or not.

These behaviours are only the reasonable defaults, you can override both.

This would change X outside the function:

def changer(x, y):
  global X
  X = 1

This would keep Y list unchanged:

def changer(x, y):
  z = y[:]  # make a copy of y list
  z[0] = "spam"

But, you know, I'm not sure what I said here is exactly right.. if you know
otherwise, please correct me!

  
> 
> Also, does anyone have an opinion on the Python Essential Referance from
> New Riders? How does it compare to O'Reilly's Programming Python or their
> Standard Library book?
> 
> Thanks!
> Kit
> 
> -- 
>  * Bring to me a handful of stardust,  *    Kit O'Connell
> * that I can cast into my darkest night *   vulpine@pobox.com
>  *	-Dream Trybe, "Come Down"      *    http://www.dreamspeakers.net/
> *       http://www.dreamtrybe.com/      *   Austin, Texas, Planet Earth
> 			'finger vulpine@io.com' for PGP key
> 
> 
> _______________________________________________
> Tutor maillist  -  Tutor@python.org
> http://mail.python.org/mailman/listinfo/tutor

-- 
Cymbaline: intelligent learning mp3 player - python, linux, console.
get it at: cy.silmarill.org