1

This should be simple...

class Object:
    x = 0
    y = []

a = Object()
b = Object()

a.x = 1
b.x = 2
print a.x, b.x
# output: 1 2
# works as expected

a.y.append(3)
b.y.append(4)
print a.y, b.y
# output: [3, 4] [3, 4]
# same list is referenced  how to fix?
# desired output: [3] [4]

As far as I can tell, a.y and b.y reference the same list. How can I get them to be separate? Preferably, without adding an __init__ method.

devtk
  • 1,999
  • 2
  • 18
  • 24

4 Answers4

3

You're creating the value of y only once, when you define the class. To assign a different list to each instance of y, you do need an init function. Just put self.y = [] in __init__ and it will work as intended.

alexis
  • 48,685
  • 16
  • 101
  • 161
2

What's happening here is that you actually have actually redefined x as an instance level attribute, and your class definition had them as both class level attributes.

If you do this, you can see your original x is still at 0.

>>> Object.x
0

As you don't create a new list, it's taking the class attribute. If you were to do this:

>>> a.y = []
>>> b.y = []
>>> a.y.append(1)
>>> b.y.append(2)
>>> print a.y, b.y
[1] [2]

That is what you are expecting. Really though you should be defining your class like this:

class Object(object):
    def __init__(self):
        self.y = []
        self.x = 0

(and don't use Object as a classname!)

Andrew Barrett
  • 19,721
  • 4
  • 47
  • 52
  • Beautiful explanation, thank you! And don't worry, my real objects are not `Object`s :) – devtk May 03 '12 at 21:14
1

The easiest way to setup instance properties instead of class properties is to use __init__

When you reference an instance property (like a.y) the parser tries to return that first but if it isn't found the class property (Object.y) is returned.

In your case only defined a class property which is shared by all instances.

KurzedMetal
  • 12,540
  • 6
  • 39
  • 65
1

The only way to do that is creating the __init__ method

class Object:
  def __init__(self):
    self.x = 0
    self.y = []

That way upon Object's construction, a new value will be assined to x and a new List will be created for y.

The way you were doing before creates two class/static variables to Object, but only y stays the same because it holds statically only a reference to the true List, reflecting to all instances of Object.

More on class/static variables on this other question: Static class variables in Python

*Sorry if I used the wrong terms, I'm more of a Java person ;-)

Community
  • 1
  • 1