![]() |
scope, function, mutable
Hi,
What is the appropriate definition for the following behavior in Python 2.7 (see code below). Both functions have assignment in it (like "x = ") so I assume, that x is a local variable in both functions. Also I thought this rule doesn't depend on WHERE in this function we find the assignment. But in both functions x becomes local variable only AFTER assignment, so in f2 x[1] = 99 changes the global varialble (btw, x[3] = 99 doesn't). def f1(x): x = [44] + x[1:] x[1] = 99 def f2(x): x[1] = 99 x = [44] + x[1:] x[3] = 99 t = [1,2,3,4,5,6,7] f1(t) print t # [1, 2, 3, 4, 5, 6, 7] t = [1,2,3,4,5,6,7] f2(t) print t # [1, 99, 3, 4, 5, 6, 7] Thank you. Roman Gusarev. |
Re: scope, function, mutable
On Tue, 04 Dec 2012 14:55:44 +0400, gusarer wrote:
> What is the appropriate definition for the following behavior in Python > 2.7 (see code below). > Both functions have assignment in it (like "x = ") so I assume, that x > is a local variable in both functions. Well, yes, but that's not why x is local in this case. In this case, x is local because the name of the function parameter is "x", and function parameters are always local. > Also I thought this rule doesn't depend on WHERE in this function we > find the assignment. > > But in both functions x becomes local variable only AFTER assignment, Not so. Read on. > so > in f2 x[1] = 99 changes the global varialble (btw, x[3] = 99 doesn't). > > def f1(x): > x = [44] + x[1:] > x[1] = 99 When you call f1(t), with t a global list, Python passes the list object to the function and binds it to name x. The function gets executed like this pseudo-code: # calling f1(t) pass object known as "t" to the function bind that object to the local name "x" create a new list: [44] + a slice of x bind this new list to name "x" modify in place item 1 of the new list known as "x" Notice that the only *modification* occurs after a new list is created and bound to the name "x", so the modification does not change the original, global, list. But now consider your other function: > def f2(x): > x[1] = 99 > x = [44] + x[1:] > x[3] = 99 In pseudo-code again: # calling f2(t) pass object known as "t" to the function bind that object to the local name "x" modify in place item 1 of the list known as "x", which is another name for the global list known as "t" create a new list: [44] + a slice of x bind this new list to name "x" modify in place item 3 of the new list known as "x" So in this case you have to in-place modifications. The first occurs while the name "x" still refers to the original list, and so it modifies the original list. The second occurs after the name "x" has been rebound to a new list, and so it doesn't change the original. -- Steven |
Re: scope, function, mutable
gusarer@gmail.com writes:
> What is the appropriate definition for the following behavior in > Python 2.7 (see code below). > > Both functions have assignment in it (like "x = ") so I assume, that > x is a local variable in both functions. It's a local variable in both functions because it's a formal parameter in both. The assignments don't make any difference here. (And a statement like x[k] = ... never does.) > Also I thought this rule doesn't depend on WHERE in this function we > find the assignment. That's correct but not relevant here. It's relevant when the variable does not occur in the function's parameter list. > But in both functions x becomes local variable only AFTER > assignment, so in f2 x[1] = 99 changes the global varialble (btw, > x[3] = 99 doesn't). In both functions, x is local from the start. Its initial value is the same mutable object that is the value of the global variable t. The assignments x = [44] ... give it a new value, another mutable object, but x[k] = ... don't. The latter make a change in the old value which is still the value of the globale variable t. > def f1(x): > x = [44] + x[1:] > x[1] = 99 > > def f2(x): > x[1] = 99 > x = [44] + x[1:] > x[3] = 99 > > t = [1,2,3,4,5,6,7] > f1(t) > print t # [1, 2, 3, 4, 5, 6, 7] > t = [1,2,3,4,5,6,7] > f2(t) > print t # [1, 99, 3, 4, 5, 6, 7] You might want to consider something like the following, because the point really has everything to do with the fact that mutable objects are not copied when they are passed to functions, assigned to variables, or stored somewhere like a list, and little to do with global vs local (other than there being different variables with the same name). t = [1,2,3] u = [1,2,3] w = u w[1] = 0 u = t Some people will tell you to use different words but the behaviour of the language doesn't change. |
| All times are GMT. The time now is 04:14 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.