Class properties and object properties
Diez B. Roggisch
deets at nospam.web.de
Mon Oct 6 09:29:55 EDT 2008
SuperZE wrote:
> Learning python I was rewriting some of my old programs to see the
> pros and cons of python when a steped in some weird (at least for me)
> behavior.
>
> Here it is simplified
>
> The code:
>
>>>> class Test1:
> myList = [4 for n in range(4)]
> myInt = 4
>>>> a = Test1()
>>>> b = Test1()
>>>> a.myList
> [4, 4, 4, 4]
>>>> a.myInt
> 4
>>>> b.myList
> [4, 4, 4, 4]
>>>> b.myInt
> 4
>>>> b.myList[2] = 3
>>>> b.myInt = 3
>>>> b.myList
> [4, 4, 3, 4]
>>>> b.myInt
> 3
>>>> a.myList
> [4, 4, 3, 4]
>>>> a.myInt
> 4
>
>
> I would not expect the second a.myList to have changed as it did
> since, for me, I have only changed b.myList. And also, why only the
> list changed and not the integer?
>
> One thing i tried was:
>
>>>> class Test2:
> myList = []
> myInt = 4
> def __init__(self):
> self.myList = [4 for n in range(4)]
>
>>>> a = Test2()
>>>> b = Test2()
>>>> a.myList
> [4, 4, 4, 4]
>>>> b.myList
> [4, 4, 4, 4]
>>>> b.myList[2] = 3
>>>> b.myList
> [4, 4, 3, 4]
>>>> a.myList
> [4, 4, 4, 4]
>
>
> And as you see it worked as I expected.
>
> Now the question, why?
Because you declare myList to be a *class*-level variable, which means *all*
instances of that class (a and b in your case) *share* it. Python does not
declare *instance* variables the way you do.
Instead, do this:
class Foo(object):
def __init__(self):
self.myList = []
And to avoid a common pitfall you are likely to hit next: default arguments
in functions (and methods) are evaluated only *once*, when defined - not
later!
So
def foo(some_arg=[]):
some_arg.append("a")
print some_arg
foo()
foo()
will result in
['a']
['a', 'a']
being printed out.
Diez
More information about the Python-list
mailing list