IsString

Tom Anderson twic at urchin.earth.li
Wed Dec 14 13:58:15 EST 2005


On Tue, 13 Dec 2005, Mike Meyer wrote:

> You can show the same difference in behavior between Python and C (for 
> example) without using a function call.

Really? You certainly don't do that with the code below.

> Here's C:
>
> #include <assert.h>
>
> main() {
>  int i, *ref ;
>  i = 1 ;
>  ref = &i ;	/* Save identity of i */

Here, ref is a reference to a variable.

>  i = 2 ;
>  assert(ref == &i) ;

Here, you're comparing the addresses of variables.

> }
>
> This runs just fine; i is the same object throughout the program.
>
> On the other hand, the equivalent Python:
>
>>>> i = 1
>>>> ref = id(i)	# Save the identity of i

Here, ref is a reference to a value.

>>>> i = 2
>>>> assert ref == id(i)

Here, you're comparing values.

> Traceback (most recent call last):
>  File "<stdin>", line 1, in ?
> AssertionError
>>>>
>
> Blows up - i is no longer the same object.

Right, because the two bits of code are doing quite different things.

> Python does call by reference, which means that it passes pointers to 
> objects by value.

That's not what call by reference is - call by reference is passing 
pointers to *variables* by value.

> C is call by value, faking call by reference by passing reference 
> values. The real difference is that in C, you can get a reference to a 
> variable to pass, allowing you to change the variable. In python, you 
> can't get a reference to a name (one of the reasons we call them "names" 
> instead of "variables"), so you can't pass a value that will let the 
> called function change it.

Kinda. Here's a python translation of Steven's incrementing function 
example:

def increment(n):
 	"""Add one to the argument changing it in place."""
 	# python (rightly) doesn't have references to variables
 	# so i will use a 2-tuple (namespace, name) to fake them
 	# n should be such a 2-tuple
 	n_namespace = n[0]
 	n_name = n[1]
 	n_namespace[n_name] += 1

x = 1
increment((locals(), "x")) 
assert x == 2

This is an evil, festering, bletcherous hack, but it is a direct 
translation of the use of pass-by-reference in C.

As a bonus, here's a similarly literal python translation of your C 
program:

>>> i = 1
>>> ref = "i"
>>> i = 2
>>> assert ref == "i"

tom

-- 
The sky above the port was the colour of television, tuned to a dead
channel



More information about the Python-list mailing list