stensootla
stensootla

Reputation: 14875

python class instances referring to same location

I have a class called Door and a class called Window. It's a child class to a class named Furniture. My program reads excel files, loops over it 2 times, first time reading / writing everything about doors , the second time about windows. Simplified, I have the following code:

for gathering_inf in ('door', 'window'):
    for row in file:
        if gathering_inf == 'door' and currently reading door line:
            furniture = Door(width, height, description)
        if gatherig_inf == 'window' and currently reading window line:
            furniture = Window(width, height, description)

        # Now do something with the furniture object ..

The weird think that happens is, if I for example (as shown above) print the object furniture, I get their location and, some of the objects' location in memory is the same, even though they are two different instances width different attributes. For example:

<__main__.Door object at 0x03BFE810>
<__main__.Door object at 0x03BFE890>
<__main__.Door object at 0x03BFE810>
<__main__.Door object at 0x03BFE890>
<__main__.Door object at 0x03BFE8B0>
<__main__.Door object at 0x03BFE8D0>
<__main__.Door object at 0x03BFE8B0>
<__main__.Window object at 0x03BFE8D0>
<__main__.Window object at 0x03BFE8B0>
<__main__.Window object at 0x03BFE890>
<__main__.Window object at 0x03BFE8B0>
<__main__.Window object at 0x03BFE890>
<__main__.Window object at 0x03BFE8B0>
<__main__.Window object at 0x03BFE890>
<__main__.Window object at 0x03BFE8B0>
<__main__.Window object at 0x03BFE890>

Could someone explain to me why python behaves this way?

Upvotes: 2

Views: 231

Answers (2)

NlightNFotis
NlightNFotis

Reputation: 9805

ThiefMaster pretty much nailed it: It's the way that the Python Virtual Machine works.

What you are observing is the specifics of the CPython implemetaion of the Reference counting Garbage collector. CPython in your case is garbage collecting the Door object, and then creating a new Window object, and then reuses the (now garbage collected) Door object's location, storing the Window object there.

It is in fact common to see CPython reuse addresses of objects that were previously garbage collected. For instance, running ThiefMaster's code on my computer I got slightly different (rotational) results:

CPython memory usage

At this point it is important to note that this behaviour is CPython specific. For instance, Enthought's Python Distribution doesn't seem to produce similar results, however I do not know if this inconsistency is a matter of implementation difference:

enter image description here

Upvotes: 1

ThiefMaster
ThiefMaster

Reputation: 318518

That's because of the reference-counting garbage collector. As soon as a new object is assigned to furniture the GC will delete the object and thus its memory location can be re-used by a new object.


Here's a small demo showing this behaviour. Note that because of the way the Python REPL works (it keeps a reference to the last result in _) the addresses will alternate.

>>> foo = object(); foo
<object object at 0x7fd74cd390a0>
>>> foo = object(); foo
<object object at 0x7fd74cd390b0>
>>> foo = object(); foo
<object object at 0x7fd74cd390a0>
>>> foo = object(); foo
<object object at 0x7fd74cd390b0>
>>> foo = object(); foo
<object object at 0x7fd74cd390a0>

Upvotes: 4

Related Questions