array in class

Diez B. Roggisch deets at nospam.web.de
Tue May 13 06:19:35 EDT 2008


alefajnie wrote:

> class A:
>    this_is_original_variable_only_for_one_inctance = 0
> 
>    def __init__(self, v):
>    self.this_is_original_variable_only_for_one_inctance = v
> 
> 
> class B:
>   this_is_common_for_all_instances = []
> 
>   def __init__(self, v):
>     self.this_is_common_for_all_instances.append(v)
> 
> 
> ----------------
> now I can create some instances of B, but all of them have the same
> array, why
> 
> if I use append for b1.this_is_common_for_all_instances, the b2, b3
> will have been changed that array.
> (where bi is instance of B)
> but changes on this_is_original_variable_only_for_one_inctance works
> fine
> 
> why it does that?
> and how create array in class - normal array, "private variable"

BOTH are at first class-wide. The difference is that the list is mutable,
and thus you alter the one list, whereas a number is not - and instead you
rebind a new object under the name now in the instance itself.

You need to understand that the way you "declared" the variables above is
NOT the way instance variables work in python. It can serve as neat trick
to initialize variables to common values - but *only* if you really know
the semantics.

Instead, the idiom for creating instance-variables (that you wrongly
called "private") is this:

class Foo(object):
   def __init__(self, some_value):
       self.some_var = some_value

The reason why the above seems to work is that a lookup of a name in python
on an instance is done like this:

if hasattr(self, name):
   return getattr(self, name)
else if hasattr(self.__class__, name):
   return getattr(self.__class__, name)

That is the reason why

class Foo(object):
    bar = 10
 
    def __init__(self):
        print self.bar

sees the 10 - it will first lookup on self, fail, and then lookup on Foo,
and succedd.

However, the assignment is *always* on the instance, or spelled out like
this:

setattr(self, name, value)

Thus 

self.name = 20

will create a new variable named "name" with the object it points to being
20.

There are some minor details here regarding the descriptor protocol and
such, but these aren't important for now.

So - stop "declaring" variables if you want them to be per-instance. Use the
above mentioned idiom of setting them on self inside __init__

Diez



More information about the Python-list mailing list