1

I read that the assign in python does not copy it works like it does in c where it assigns a pointer to an object.

But when I debug this function:

def popall(self):
    objs = self.curstack
    self.curstack = []
    return objs

It looks like some kind of copy is taking place. After this function runs obis is full of things and self.curstack is empty…

So some copy is going on. Is it deep or shallow?

Stephen Lin
  • 4,852
  • 1
  • 13
  • 26
user2444342
  • 149
  • 1
  • 8

5 Answers5

6

It doesn't copy anything. It's just that assigning to self.curstack does not modify whatever self.curstack used to refer to. It just makes self.curstack refer to something else.

Think of it this way. self.curstack points to some stuff. With objs = self.curstack you make objs point to that same stuff. With self.curstack = [], you make self.curstack point to an empty list. This doesn't remove any of the stuff that self.curstack used to point at; that stuff is still there and objs is still pointing at it.

This article explains it using a nice analogy of label tags.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
2

Python uses references everywhere. So your code works like this:

objs = self.curstack

Now objs points to whatever curstack was.

self.curstack = []

Now curstack points to an empty list. objs is unchanged, and points to the old curstack.

return objs

You return objs, which is the old curstack.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
2

As mentioned in all the answers that self.curstack doesn't modify it just refer to something. In you case it is referring to an empty list [].

You can actually see the how objects are referring using swampy

 from swampy.Lumpy import Lumpy

class ref_test:

    def __init__(self, curstack):
        self.curstack = curstack

    def popall(self): 
        lampy = Lumpy()
        objs = self.curstack 
        self.curstack = [] 
        print id(self.curstack), id(objs)
        lampy.object_diagram()
        return objs

o = ref_test([1,2,3,4])
res = o.popall()
print res

enter image description here

As you can see self.curstack is pointing to an empty list and objs is still holding up the old values of self.curstack.

You can use id function to check “identity” of an object. Which is not unique in our case for self.curstack and objs

164711692 163838732
Tanveer Alam
  • 5,185
  • 4
  • 22
  • 43
1

In Python, there are two spaces, the namespace and the object space.

Names are just labels you assign to objects, which live in the object space. Objects have values and types; names are just there for our convenience; so that we may access things in the object space.

This is different than other languages like C where the variable is more like a box in which you can put a certain type of thing.

In Python, names can point to any object of any type - they are just aliases.

When you assign a name to an object, like this:

a = 1

a is just a label that points to the object 1 that has a type (int) and a value. If you next do this:

b = 1

Now you have two names a and b pointing to the same object - they are not "copies", but just two labels to the same object.

When you do this:

a = 'hello'

Now a is pointing to a new object, but b is still pointing to the old object (1).

Eventually, when no names are pointing to objects, Python does automatic garbage collection to keep the object space optimized.

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
0

Let's demonstrate what's really going on (using id which shows the location of the memory)

a = [1,2,3]
print id(a)
b = a
print id(b)
a = 4
print id(a)
print a
print b

4339130240

4339130240

4298163184

4

[1, 2, 3]

So a and b initially point to the same place in memory, but then a points somewhere new. But now, let's try

a = [1,2,3]
print id(a)
b = a
print id(b)
a[0] = 4
print id(a)
print a
print b

4339098040

4339098040

4339098040

[4, 2, 3]

[4, 2, 3]

So b isn't a fresh new copy of a. It is the same object as a (when it's defined). If you then do a=4, you're telling python, let's forget what a used to point to and assign a new meaning to it. 4 does not appear in the spot in memory that a used to refer to. Instead a now refers to a new place in memory. b still refers to what a initially referred to.

If we don't reassign a, but instead we change one of the things within the object that a points to, then checking b shows that the corresponding change happens to b.

Joel
  • 22,598
  • 6
  • 69
  • 93