scared about refrences...

Gabriel Genellina gagsl-py at yahoo.com.ar
Fri Nov 3 00:34:16 CET 2006


At Thursday 2/11/2006 19:23, SpreadTooThin wrote:

>I realize I may be beating a dead horse here... but...
>
>def fn(x):
>    x = x + 1
>    print x
>a = 2
>fn(a)
> >>> 3
>print a
> >>> 2
>
>So in some cases the it is safe to assume that your variables to
>function will not
>change in other cases it is not.. but they are all the same...

Forget about variables!
In Python you have objects. Objects don't have a name, but you may 
use a name to refer to them.
In the code above, `a` is not a variable, neither an object; it's 
just a name referring to an object (a name bound to an object); such 
object is  an instance of type int, with value 2, to be precise. 
fn(a) calls function fn [in fact, "the object bound to the name fn"] 
passing an object -the object referenced by the name `a`- as its only argument.
Inside function fn, it gets a single argument bound to the name x. 
You do some math and bind the resulting object to the local name `x`. 
Now x refers to another instance of type int, with value 3. The 
original int object is not modified - and never could have been, 
since int's are immutable, you cant change them (a 2 will always be a 
2: if you get a 3, it's ANOTHER object).
After function fn finishes, execution continues with the `print a` 
statement. Nobody has changed the object pointed by the name `a`, so 
it's still the int with value 2, and that's what you get.

All objects have identity. You can test identity using the `is` 
operator: `a is b` returns True iff both objects are identical (both 
are "the same object" just being referred by another name). The 
function id() returns the object identity.

Some objects (by example, containers like lists and dicts) are 
mutable. That means that you can change it's value, but the remain 
being the same object. By example:

--- begin test.py ---
def g(x):
   print 'x[1], in:', x[1]
   x[1] = 10
   print 'x[1], out:', x[1]

a1=1
a2=2
a3=3
foo=[a1,a2,a3]
print "before, foo=",foo,"id(foo)=",id(foo)
print "a2=",a2,"id(a2)=",id(a2)
g(foo)
print "after, foo=",foo,"id(foo)=",id(foo)
print "a2=",a2,"id(a2)=",id(a2)
--- end test.py ---
Output:

before, foo= [1, 2, 3] id(foo)= 12350728
a2= 2 id(a2)= 11163404
x[1], in: 2
x[1], out: 10
after, foo= [1, 10, 3] id(foo)= 12350728
a2= 2 id(a2)= 11163404

Function g modifies the second "slot" in the list - it does not 
modify the object already in that place, it just makes the second 
item in the list to refer to another object (the int 10). The 
previous reference (the int 2) is lost.
Anyway, the list remains "the same" (look at id(foo)).
The name a2 still refers to the int 2 (because nobody changed that).

It's really easy once you get it - and then, just enjoy writing Python code!


-- 
Gabriel Genellina
Softlab SRL 

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis! 
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar



More information about the Python-list mailing list