unexpected behavior: did i create a pointer?

A

Arnaud Delobelle

You're almost certainly wrong. He would have written to ask why this
doesn't do what he expects:

This means that x now points to the value of x + 1, i.e. an int object
with value 4.

Of course not, now x points to 4 and y points to 3 !
False

Or why lower_list() works as expected, but lower_string() doesn't:

... for i, x in enumerate(L):
... L = x.lower()
...>>> s = ['STRING']
lower_list(s)
print s == ['string']
True
def lower_string(s):

... s = s.lower()
...>>> s = "STRING"


Let's see what happens here: when lower_string(s) is called, the 's'
which is local to lower_string is made to point to the same object as
the global s (i.e. the string object with value "STRING"). In the
body of the function, the statement s=s.lower() makes the local 's'
point to a new string object returned s.lower(). Of course this has
not effect on what object the global 's' points to.

Obviously not, since s still points to the string object with value
"STRING"
False

The "names in Python are pointers" analogy only gives you the right
answer half the time.

They give *you* the right answer only half the time ;)

They give me the right answer all the time. Not that I usually think
of names as pointers. But if I choose to do so, I can still get it
right. And if it works for me consistently, there must be some
validity in it, no?

What I think is a more dangerous misconception is to think that the
assignement operator (=) has the same meaning in C and python.
 
A

Alex Martelli

Arnaud Delobelle said:
def lower_list(L):

... for i, x in enumerate(L):
... L = x.lower()
...>>> s = ['STRING']
lower_list(s)
print s == ['string'] True

def lower_string(s):

... s = s.lower()
...>>> s = "STRING"
lower_string(s)


Let's see what happens here: when lower_string(s) is called, the 's'
which is local to lower_string is made to point to the same object as
the global s (i.e. the string object with value "STRING"). In the
body of the function, the statement s=s.lower() makes the local 's'
point to a new string object returned s.lower(). Of course this has
not effect on what object the global 's' points to.


Yep, the analogy with C pointers would work fine here:

void lower_string(char* s) {
s = <whatever>
}

would fail to have the intended effect in C just as its equivalent does
in Python (in both Python and C, rebinding the local name s has no
effect on the caller of lower_string). Add an indirection:

void lower_list(item* L) {
...
L = <something>
}

this indirection (via indexing) *does* modify the memory area (visible
by the caller) to which L points.

The difference between "name=something" and "name=something" is so
*HUGE* in C (and in Python) that anybody who doesn't grok that
difference just doesn't know or understand any C (nor any Python).

What I think is a more dangerous misconception is to think that the
assignement operator (=) has the same meaning in C and python.

I've seen the prevalence of that particular misconception drop
dramatically over the years, as a growing fraction of the people who
come to Python after some previous programming experience become more
and more likely to have been exposed to *Java*, where assignment
semantics are very close to Python (despite Java's unfortunate
complication with "unboxed" elementary scalar types, in practice a vast
majority of occurrences of "a=b" in Java have just the same semantics as
they do in Python); teaching Python semantics to people with Java
exposure is trivially easy (moving from "ALMOST every variable is an
implicit reference -- excepting int and float ones" to "EVERY variable
is an implicit reference"...).


Alex
 
N

neoedmund

hi to all!
after two days debugging my code, i've come to the point that the
problem was caused by an unexpected behaviour of python. or by lack of
some information about the program, of course! i've stripped down the
code to reproduce the problem:

<code>
a = {}

for x in range(10):
for y in range(10):
a[x,y] = "0"

copyOfA = a

def functionA(x,y):
print a[x,y],
copyOfA[x,y] = "*"
print a[x,y],copyOfA[x,y]

for x in range(10):
for y in range(10):
functionA(x,y)

</code>

now, in the second "for" cycle and in functionA() i only 'touch' copyOfA
(altering it). as i don't touch the variable "a", i expect it not to be
affected by any change, but copyOfA acts like a pointer to a and
altering copyOfA's values result in altering the values of "a", so the
result that i expect is:
0 0 *
0 0 *
0 0 *
0 0 *
[..]

but i get:
0 * *
0 * *
0 * *
0 * *
[..]

what's going on?
thanks in advance.

no language act like want you tought, or the assignment operation will
be too expensive.
 
P

Peter Otten

Am Sat, 08 Sep 2007 09:44:24 +0000 schrieb Steven D'Aprano:
Ways that Python objects are not like C pointers:

(1) You don't have to manage memory yourself.

(2) You don't have typecasts. You can't change the type of the object you
point to.

(3) Python makes no promises about the memory location of objects.

(4) No pointer arithmetic.

(5) No pointers to pointers, and for old-school Mac programmers, no
handles.

(6) No dangling pointers. Ever.

(7) There's no null pointer. None is an object, just like everything else.

(8) You can't crash your computer by writing the wrong thing to the wrong
pointer. You're unlikely even to crash your Python session.



Ways that Python objects are like pointers:

(1) ... um...

Oh yeah, if you bind the _same_ object to two different names, _and_ the
object is mutable (but not if it is immutable), mutating the object via
one name will have the same effect on the object -- the same object,
naturally -- bound to the other name.

Had you put it that way in the first place I would have stayed in in my
hole ;)

Peter
 
B

Bruno Desthuilliers

neoedmund a écrit :
(snip)
no language act like want you tought, or the assignment operation will
be too expensive.

IIRC, php4 was doing copies for arrays...
 
G

Gabriel Genellina

En Wed, 12 Sep 2007 08:30:14 -0300, Bruno Desthuilliers
neoedmund a écrit :

IIRC, php4 was doing copies for arrays...

Pascal does copy arrays and structs (records) too.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top