If you're ever learning Python, just remember this one thing:

Jul 17, 2006 17:07

If you're ever doing a foreach style iteration over a collection a la for object in objects:, object isn't a pointer or a reference, but a copy of what was in your collection. If you can remember this, you'll save yourself a couple hours of bashing your head on the wall and wondering where the hell your data was going ( Read more... )

pain, python, work, programming

Leave a comment

annodomini July 18 2006, 01:36:13 UTC
Well, I wouldn't say that you're getting a copy of the object; there is no copying going on, other than (potentially) the copying of the pointer to the object. Basically, every object has an identity and a value; the value can be mutable or immutable. The identity would be implemented as a pointer for compound objects, but for simple objects like numbers, is just the number itself. Some objects like numbers and strings are immutable, while others like lists are mutable. When you do a foreach style iteration, the identity of object is the same as the identity of one of the items in the list, so copying certainly isn't happening.

Now, you also have names that refer to these objects. There can be many different names that refer to the same object, and a name can refer to different objects at different times. When you perform assignment, or binding, you don't change the identity of any particular object, and you don't mutate any objects, you change which object a particular name points to. This is how the object variable in a loop like for object in objects works; it is a name that is assigned a different value in each iteration of the loop.

So, for instance, if you have something like the following, you will not actually modify the list; what you are doing is modifying which object thing points to:

list = [1, 2, 3]
for thing in list
thing = thing + 1
But if you have some objects, foo, bar, and baz that have some member called member, the following code will change each of the objects in the list, demonstrating that they are actually being manipulated by pointer/reference:

list = [foo, bar, baz]
for thing in list
thing.member = thing.member + 1
I'm assuming that you wanted something like the first example to modify the list itself. The way to do that in Python is:

for i in range(len(list))
list[i] = list[i] + 1
I think your confusion stems from thinking of lists in Python the way you think of arrays in C where items are inline, and you use a pointer to traverse the list. The thing is, in C, a pointer to one of the objects in the list is also a pointer to that location in the list, so if you modify the thing it points to, you're modifying that location in the list. In Python (and almost every other high-level language, like Java, Scheme, Ruby, Lisp), everything that's not atomic is passed around by pointer, and you get the pointer to the object itself in your iterators, not a pointer to the location in the collection.

Sorry for the lecture, I just wanted to make sure you didn't think a copy of the full object was happening in your iterator, since that would come back to bite you later when you assumed it wasn't being modified.

Reply

hyuga July 18 2006, 03:06:02 UTC
Yeah, I figured out that I had to do like in your last example. And I know my wording wasn't quite right--I didn't mean to imply that the entire object was being copied. That would take way too long, especially for relatively large objects. Now that I look at it, I'm not sure what I meant--I still wasn't entirely sure what was going on.

I had a collection of objects of class Field and subclasses thereof, and I was trying to do something like this:

for field in fields:
    if field.name == 'foo': field = FieldSubclass(field.name)

It's obvious to me now why that wouldn't have done any good.

Thanks for the lecture though--I get it now. That's the problem with high-level languages like this. Since you don't have much direct control over memory yourself, you really have to know what's going on under the hood. Not that I have anything against knowing what's going on; it just makes for a slight learning curve every time you learn a new language, since it's usually a little different. I'm surprised I've managed to do as much in Python as I already have without running into this.

Reply


Leave a comment

Up