From: Tim Harig on
On 2010-08-08, Costin Gament <costin.gament(a)gmail.com> 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.
From: Costin Gamenț on
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 <usernet(a)ilthio.net> 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.
From: Tim Harig on
On 2010-08-08, Tim Harig <usernet(a)ilthio.net> wrote:
> On 2010-08-08, Costin Gament <costin.gament(a)gmail.com> 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.
From: Tim Harig on
On 2010-08-08, Tim Harig <usernet(a)ilthio.net> wrote:
> On 2010-08-08, Tim Harig <usernet(a)ilthio.net> wrote:
>> On 2010-08-08, Costin Gament <costin.gament(a)gmail.com> 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.
From: Benjamin Kaplan on
On Sun, Aug 8, 2010 at 6:32 AM, Costin Gament <costin.gament(a)gmail.com> wrote:
>
> Hi there.
> I'm kind of a beginner with Python (and programming in general). My
> problem is with initializing a class. Let's say I've defined it like
> this:
>
> class foo:
>   a = 0
>   b = 0
>
> and later I'm trying to initialize two different classes like this:
> c1 = foo()
> c2 = foo()
>
> The problem I have is that c1 and c2 tend to point to the same
> instance, like a weird c-like pointer. Please tell me, what am I doing
> wrong?
>
> Thank you,


Python is not C++ or Java. Don't expect it to behave like them. In
Python, everything you declare in the class namespace is in the
*class* namespace. Since functions are objects too, this works out
rather nicely for the most part. Where it doesn't work is when you use
mutable variables.

Here's the example you wanted to give:

class Foo(object):
a = []
b= []


Unlike Java or C++, classes are objects too. That leads to one of the
neat tricks you can do with Python. The code above is exactly the same
thing as this

Foo = type("Foo",object, {}) #that dictionary will become Foo's list
of attributes
Foo.a = []
Foo.b = []

Now, when you call f1 = Foo(), it creates a new object. But here's
what happens when you call f1.a.append(1) :

* First, Python will look in the attributes of f1 for a. But f1
doesn't have an attribute "a".
* So it starts looking up the classes in the inheritance tree. It
looks at Foo and finds that Foo does have an attribute "a", so it
grabs that.
* Then, it looks up the attribute "append" on the a attribute (which
is a list), and calls that with the arguments Foo.a and 1.
* When f2 = Foo() goes looking for a, it finds the exact same object-
Foo.a. It doesn't have its own copy,

If you want an object to have its own copy of the variable, you have
to create the new copy when the object is created, not when the class
is created. That's why you'll see this in most Python programs :

class Foo(object) :
def __init__(self) : #self is the new object that was just created.
#now here we'll assign the attributes on the new object,
instead of the class.
self.a = []
self.b = []
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4
Prev: Renaming of files in OS directory
Next: DjangoCon 2010