why cannot assign to function call
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Fri Jan 9 11:43:39 EST 2009
On Fri, 09 Jan 2009 08:30:46 -0700, Joe Strout wrote:
> That's correct. The reference itself is passed in, not the variable (or
> expression) that held or generated the reference in the calling code.
>
> This is no different from, in C, passing an integer:
>
> void foo(int bar) {
> bar = 42;
> }
> int baz = 0;
> foo(baz);
>
> This doesn't change baz because, speaking precisely, baz wasn't passed
> to foo -- only the *value* of baz (i.e. 0) was passed to foo.
We can check whether bar and baz are the same thing, by printing their
addresses:
#include<stdio.h>
void foo(int bar) {
printf("\n The address of bar is %p ", &bar);
bar = 42;
}
int main() {
int baz = 0;
printf("\n The address of baz is %p ", &baz);
foo(baz);
return 0;
}
When I do this, I get:
The address of baz is 0xbfa72870
The address of bar is 0xbfa72850
So we can agree that baz and bar are different entities. Now, would
anyone like to take a small wager on what the equivalent code in CPython
would print?
def foo(bar):
print " The address of bar is %s " % id(bar)
bar = 42
baz = 0
print " The address of baz is %s " % id(baz)
foo(baz)
When I execute this, I get
The address of baz is 143599468
The address of bar is 143599468
Python doesn't do the same thing as C. It actually passes the same value
to the function, without copying it.
Why oh why do you keep insisting that Python is no different from C?
Let's try one more. In C:
#include <stdio.h>
#include <stdlib.h>
struct record {
int x;
};
void mutate(struct record bar) {
printf("\n The address of bar is %p ", &bar);
bar.x = 0;
printf("\n Inside: %d ", bar.x);
}
struct record baz;
int main(void) {
baz.x = 1;
printf("\n The address of baz is %p ", &baz);
printf("\n Before: %d ", baz.x);
mutate(baz);
printf("\n After: %d ", baz.x);
return 0;
}
gives output:
The address of baz is 0x80496fc
Before: 1
The address of bar is 0xbfb8f980
Inside: 0
After: 1
We can clearly see that baz and bar are different entities, and changes
made to bar inside the function don't affect baz.
A Python equivalent:
class struct: pass
def mutate(bar):
print " The address of bar is %d " % id(bar)
bar.x = 0;
print " Inside: %d " % bar.x
baz = struct()
baz.x = 1
print " The address of baz is %d " % id(baz)
print " Before: %d " % baz.x
mutate(baz)
print " After: %d " % baz.x
which gives output:
The address of baz is 3085537420
Before: 1
The address of bar is 3085537420
Inside: 0
After: 0
Why oh why do you keep insisting that Python is no different from C?
--
Steven
More information about the Python-list
mailing list