Re: Class initialization

Discussion in 'Python' started by Costin Gament, Aug 8, 2010.

  1. Thank you for your answer, but it seems I didn't make myself clear.
    Take the code:
    class foo:
    a = 0
    b = 0
    c1 = foo()
    c1.a = 5
    c2 = foo()
    print c2.a
    5

    Somehow, when I try to acces the 'a' variable in c2 it has the same
    value as the 'a' variable in c1. Am I missing something?

    On Sun, Aug 8, 2010 at 4:59 PM, Roald de Vries <> wrote:
    >
    > Your problem probably is that a and b are class variables; c1 and c2 are
    > different objects (in your terminology: they point to different instances).
    >
    > See http://docs.python.org/tutorial/classes.html#class-objects for more
    > info.
    >
    > Cheers, Roald
    >
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
     
    Costin Gament, Aug 8, 2010
    #1
    1. Advertising

  2. On Sun, 08 Aug 2010 17:14:08 +0300, Costin Gament wrote:

    > Thank you for your answer, but it seems I didn't make myself clear. Take
    > the code:
    > class foo:
    > a = 0
    > b = 0
    > c1 = foo()
    > c1.a = 5
    > c2 = foo()
    > print c2.a
    > 5


    Incorrect.

    >>> class foo:

    .... a = 0
    .... b = 0
    ....
    >>> c1 = foo()
    >>> c1.a = 5
    >>> c2 = foo()
    >>> print c2.a

    0



    --
    Steven
     
    Steven D'Aprano, Aug 8, 2010
    #2
    1. Advertising

  3. Apparently, the code I've given here does, in fact, work. Still, I am
    encountering a similar problem in a much larger class (it is in a
    separate module, if that is any help). Also, the variable I am having
    trouble with is itself another class. I don't think it's appropriate
    to paste so much code in here, so if anybody has some knowledge about
    similar problems...

    On Sun, Aug 8, 2010 at 5:49 PM, Steven D'Aprano
    <> wrote:
    > On Sun, 08 Aug 2010 17:14:08 +0300, Costin Gament wrote:
    >
    >> Thank you for your answer, but it seems I didn't make myself clear. Take
    >> the code:
    >> class foo:
    >>   a = 0
    >>   b = 0
    >> c1 = foo()
    >> c1.a = 5
    >> c2 = foo()
    >> print c2.a
    >> 5

    >
    > Incorrect.
    >
    >>>> class foo:

    > ...   a = 0
    > ...   b = 0
    > ...
    >>>> c1 = foo()
    >>>> c1.a = 5
    >>>> c2 = foo()
    >>>> print c2.a

    > 0
    >
    >
    >
    > --
    > Steven
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
     
    Costin Gament, Aug 8, 2010
    #3
  4. Costin Gament

    Tim Harig Guest

    On 2010-08-08, Costin Gament <> wrote:
    > Thank you for your answer, but it seems I didn't make myself clear.
    > Take the code:
    > class foo:
    > a = 0
    > b = 0
    > c1 = foo()
    > c1.a = 5
    > c2 = foo()
    > print c2.a
    > 5
    >
    > Somehow, when I try to acces the 'a' variable in c2 it has the same
    > value as the 'a' variable in c1. Am I missing something?


    Others have told you that at a and b belong to the class object rather then
    to the instance objects. Perhaps this will demonstrate the difference:

    >>> class foo():

    .... def __init__(self):
    .... self.a = 0
    .... self.b = 0
    ....
    >>> c1 = foo()
    >>> c1.a = 5
    >>> c2 = foo()
    >>> print c2.a

    0
    >>>
     
    Tim Harig, Aug 8, 2010
    #4
  5. On Sun, Aug 8, 2010 at 10:01 AM, Tim Harig <> wrote:
    > On 2010-08-08, Costin Gament <> wrote:
    >> Thank you for your answer, but it seems I didn't make myself clear.
    >> Take the code:
    >> class foo:
    >>   a = 0
    >>   b = 0
    >> c1 = foo()
    >> c1.a = 5
    >> c2 = foo()
    >> print c2.a
    >> 5
    >>
    >> Somehow, when I try to acces the 'a' variable in c2 it has the same
    >> value as the 'a' variable in c1. Am I missing something?

    >
    > Others have told you that at a and b belong to the class object rather then
    > to the instance objects.  Perhaps this will demonstrate the difference:
    >
    >>>> class foo():

    > ...     def __init__(self):
    > ...             self.a = 0
    > ...             self.b = 0
    > ...
    >>>> c1 = foo()
    >>>> c1.a = 5
    >>>> c2 = foo()
    >>>> print c2.a

    > 0
    >>>>

    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >


    Is it possible that you are using a mutable class object? A common
    gotcha is to do something like this:

    >>> class foo(object):

    .... x = []
    ....
    >>> a = foo()
    >>> b = foo()
    >>> a.x.append(123)
    >>> b.x

    [123]

    And expect b.x to be an empty list.
     
    Jesse Jaggars, Aug 8, 2010
    #5
  6. So you're saying I should just use __init__? Will that get me out of
    my predicament?
    No, I don't quite understand the difference between my exemple and
    using __init__, but I will read the docs about it.

    On Sun, Aug 8, 2010 at 6:01 PM, Tim Harig <> wrote:
    >
    > Others have told you that at a and b belong to the class object rather then
    > to the instance objects.  Perhaps this will demonstrate the difference:
    >
    >>>> class foo():

    > ...     def __init__(self):
    > ...             self.a = 0
    > ...             self.b = 0
    > ...
    >>>> c1 = foo()
    >>>> c1.a = 5
    >>>> c2 = foo()
    >>>> print c2.a

    > 0
    >>>>
     
    Costin Gament, Aug 8, 2010
    #6
  7. That looks just like my code. What's the problem?

    On Sun, Aug 8, 2010 at 6:13 PM, Jesse Jaggars <> wrote:
    >
    > Is it possible that you are using a mutable class object? A common
    > gotcha is to do something like this:
    >
    >>>> class foo(object):

    > ...   x = []
    > ...
    >>>> a = foo()
    >>>> b = foo()
    >>>> a.x.append(123)
    >>>> b.x

    > [123]
    >
    > And expect b.x to be an empty list.
     
    Costin Gament, Aug 8, 2010
    #7
  8. Costin Gament

    Tim Harig Guest

    On 2010-08-08, Costin Gament <> wrote:
    > So you're saying I should just use __init__? Will that get me out of
    > my predicament?
    > No, I don't quite understand the difference between my exemple and
    > using __init__, but I will read the docs about it.


    It is not so much using __init__() that makes the difference as it what
    scope the variables are assigned to. If you define them as you where, then
    the variables are associated with the class object itself. If the variable
    is a mutable type, and you change it in one instance, it actually changes
    it in the class object which means it also changes for all of the
    instances.

    I used the constructor because it gives me a reference to the newly created
    instance object "self". I then assign the variables to self, which
    assignes them to the newly created instance object. Then each instance has
    its own separate a and b variables that will not change when the variables
    are changed inside of another instance object.
     
    Tim Harig, Aug 8, 2010
    #8
  9. Thanks a lot. I'll try give it a go and see if it helps.

    On Sun, Aug 8, 2010 at 6:28 PM, Tim Harig <> wrote:
    > It is not so much using __init__() that makes the difference as it what
    > scope the variables are assigned to.  If you define them as you where, then
    > the variables are associated with the class object itself.  If the variable
    > is a mutable type, and you change it in one instance, it actually changes
    > it in the class object which means it also changes for all of the
    > instances.
    >
    > I used the constructor because it gives me a reference to the newly created
    > instance object "self".  I then assign the variables to self, which
    > assignes them to the newly created instance object.  Then each instance has
    > its own separate a and b variables that will not change when the variables
    > are changed inside of another instance object.
     
    Costin GamenÈ›, Aug 8, 2010
    #9
  10. Costin Gament

    Tim Harig Guest

    On 2010-08-08, Tim Harig <> wrote:
    > On 2010-08-08, Costin Gament <> wrote:
    >> So you're saying I should just use __init__? Will that get me out of
    >> my predicament?
    >> No, I don't quite understand the difference between my exemple and
    >> using __init__, but I will read the docs about it.

    >
    > It is not so much using __init__() that makes the difference as it what
    > scope the variables are assigned to. If you define them as you where, then
    > the variables are associated with the class object itself. If the variable
    > is a mutable type, and you change it in one instance, it actually changes
    > it in the class object which means it also changes for all of the
    > instances.
    >
    > I used the constructor because it gives me a reference to the newly created
    > instance object "self". I then assign the variables to self, which
    > assignes them to the newly created instance object. Then each instance has
    > its own separate a and b variables that will not change when the variables
    > are changed inside of another instance object.


    Maybe I can make that a little clearer yet. When you define a class in
    python you actually create a class object. This object is basically used
    as a template to create instance objects. When you define a variable
    attached to the class object that is mutable, the instance objects receive
    the exact same reference that was given to the instance object. Since it
    is mutable, any changes made using that reference will affect all of the
    instances that also point to that reference. You wouldn't have seen this
    effect using your simplified examle because number are immutable objects.
    When you change the value for one of the instance objects, it receives a
    new reference, rather then making the change in place. The other instances
    do not reflect this change because their variables still point back to the
    original reference given to the class.
     
    Tim Harig, Aug 8, 2010
    #10
  11. Costin Gament

    Tim Harig Guest

    On 2010-08-08, Tim Harig <> wrote:
    > On 2010-08-08, Tim Harig <> wrote:
    >> On 2010-08-08, Costin Gament <> wrote:
    >>> So you're saying I should just use __init__? Will that get me out of
    >>> my predicament?
    >>> No, I don't quite understand the difference between my exemple and
    >>> using __init__, but I will read the docs about it.

    >>
    >> It is not so much using __init__() that makes the difference as it what
    >> scope the variables are assigned to. If you define them as you where, then
    >> the variables are associated with the class object itself. If the variable
    >> is a mutable type, and you change it in one instance, it actually changes
    >> it in the class object which means it also changes for all of the
    >> instances.
    >>
    >> I used the constructor because it gives me a reference to the newly created
    >> instance object "self". I then assign the variables to self, which
    >> assignes them to the newly created instance object. Then each instance has
    >> its own separate a and b variables that will not change when the variables
    >> are changed inside of another instance object.

    >
    > Maybe I can make that a little clearer yet. When you define a class in
    > python you actually create a class object. This object is basically used
    > as a template to create instance objects. When you define a variable
    > attached to the class object that is mutable, the instance objects receive
    > the exact same reference that was given to the instance object. Since it
    > is mutable, any changes made using that reference will affect all of the
    > instances that also point to that reference. You wouldn't have seen this
    > effect using your simplified examle because number are immutable objects.
    > When you change the value for one of the instance objects, it receives a
    > new reference, rather then making the change in place. The other instances
    > do not reflect this change because their variables still point back to the
    > original reference given to the class.


    And to complete that thought, when you assign variables directly to
    the instance, as I did using the constructor's reference to self, each
    instance receives a brand new reference that is not shared among any of
    the other instances.
     
    Tim Harig, Aug 8, 2010
    #11
  12. Costin Gament

    Mel Guest

    Costin Gament wrote:

    > So you're saying I should just use __init__? Will that get me out of
    > my predicament?
    > No, I don't quite understand the difference between my exemple and
    > using __init__, but I will read the docs about it.


    Here's the thing about class variables:

    Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
    [GCC 4.3.3] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> class AClass (object):

    .... var = 5
    ....
    >>> a = AClass()
    >>> b = AClass()
    >>> a.var, b.var

    (5, 5)
    >>> AClass.var = 7
    >>> a.var, b.var

    (7, 7)
    >>> a.var = 9
    >>> a.var, b.var

    (9, 7)
    >>> a.var is AClass.var

    False
    >>> b.var is AClass.var

    True

    When `var` is defined as a variable in AClass, it belongs to AClass. But
    all the instances of AClass are allowed to access it as though it's their
    own -- it's a sensible way for Python to manage attribute lookup.

    Assigning to AClass.var changes the value as seen by all the instances.

    Assigning to a.var creates a new variable in instance a's namespace, and
    from then on that becomes the value that will be found by looking up a.var .
    The `is` test shows that this is true.

    Mel.
     
    Mel, Aug 9, 2010
    #12
  13. On Sun, 08 Aug 2010 19:47:18 -0400, Mel wrote:

    > Costin Gament wrote:
    >
    >> So you're saying I should just use __init__? Will that get me out of my
    >> predicament?
    >> No, I don't quite understand the difference between my exemple and
    >> using __init__, but I will read the docs about it.

    >
    > Here's the thing about class variables:

    [snip example]

    No, that's actually the thing about class *attributes*. This is Python,
    not Java or whatever language you're used to that uses such bizarrely
    inconsistent terminology.

    A variable holding an int is an int variable.

    A variable holding a string is a string variable.

    A variable holding a float is a float variable.

    And a variable holding a class is a class variable.

    Given a class:

    class MyClass:
    attribute = None

    MyClass is a perfectly normal variable, like any other variable you
    create in Python. You can reassign to it, you can pass it to functions,
    it has an object bound to it. In other words, it's a class variable in
    the same way that n = 2 creates an int variable.

    (Although of course because Python has dynamic typing, n is only an int
    until it gets rebound to something which isn't an int. Likewise MyClass
    is only a class until it gets rebound to something else.)

    That's why Python has builtin functions getattr, setattr and hasattr
    rather than getvar, setvar and hasvar.


    --
    Steven
     
    Steven D'Aprano, Aug 9, 2010
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JKop
    Replies:
    10
    Views:
    962
  2. Matthias Kaeppler
    Replies:
    2
    Views:
    457
    Victor Bazarov
    Jul 18, 2005
  3. Replies:
    6
    Views:
    472
    Ron Natalie
    Dec 11, 2005
  4. toton
    Replies:
    5
    Views:
    945
    Victor Bazarov
    Sep 28, 2006
  5. Jess
    Replies:
    23
    Views:
    953
Loading...

Share This Page