0

So, I have this class

class table:
    h = 0
    g = 0

And I have one element of this class called aux.

aux = table

aux.g is equal to zero.
Later I call this function move(aux)

move(x):
    newTable = table
    newTable.g = x.g + 1

newTable.g receives 1 as expected, but x.g also changes from 0 to 1. Why?
Thanks in advance, Adriano

4 Answers4

6

This is because you're declaring the equivalent of a static class variable and when you update it, it gets updated for every instance of that class. What you want is to declare instance variables like this:

class table:
    def __init__(self):
        self.h = 0
        self.g = 0

Now when you instantiate the class like this: aux = table(), it assigns the values to that instance of table - just the aux variable.

Your move function will look like this:

move(x):
    newTable = table()
    newTable.g = x.g + 1

which will increment the value of newTable.g, but not the value of x.g. You'll also probably want to return the new table like this: return newTable and you can then use it in other functions.

It's worth noting that in your code you never actually perform instantiation of the table class. This means that when you assign aux = table, it just assigns a reference to the class to your variable aux. To create an instance of a class, you call the class like you would a function - this is called a constructor - and it calls the class's __init__ method. So when I declare aux = table(), the table __init__ method is executed and then the new instance of the class is returned.

Community
  • 1
  • 1
wpercy
  • 9,636
  • 4
  • 33
  • 45
  • Note that OP doesn't actually instantiated the class at all; both `aux` and `newTable` in his code are simply references to the class itself. – Daniel Roseman Dec 16 '15 at 21:30
  • Yes I'm aware, but from the problem description I figured it was fair to assume he wanted to. I'll edit my answer to include a bit about instantiation – wpercy Dec 17 '15 at 00:22
2

h and g are static, i.e. "class variables". h and g are not unique for an object of class table, but are attributes of that class itself.

timgeb
  • 76,762
  • 20
  • 123
  • 145
2

By defining attributes just on the class they're bound to the whole class (static) and not to individual instances (aka objects). What you rather want is assigning them inside a constructor:

class Table:
    def __init__(self):
        self.h = 0
        self.g = 0

    def move(self, delta):
        self.h += deta

Note that I also changed the move function to a method. The difference is that a method changes the state of individual instances.

You can then create instances and work with them like this:

t1 = Table()
t2 = Table()
t1.move(10)
print(t1.h)   # will print 10
print(t2.h)   # will print 0
Hubert Grzeskowiak
  • 15,137
  • 5
  • 57
  • 74
2

When you did this:

aux = table

and this:

newTable = table

you did not create new object instances of the class table. You simply referenced the class table's own instance with two different variables. In short both aux and newTable reference (forgive me for doing this; point to) the same thing.

Note that h, g are shared attributes of the class table. They are shared by all instances of the class table.

Quirk
  • 1,305
  • 4
  • 15
  • 29