Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make empty list in initial attr of class?

Tags:

python

oop

Here is a code:

>>> class A(object):
...     value = []
...     def method(self, new_value):
...         self.value.append(new_value)
... 
>>> a = A()
>>> a.value
[]
>>> a.method(1)
>>> b = A()
>>> b.value
[1]
>>> b.method(2)
>>> b.value
[1, 2]
>>> a.value
[1, 2]

This happens only with lists. Is the only way to deffine value in __init__?
How to normally define default class values in python?

UPD

thank you for your responses

>>> class B(object):
...     value = "str"
...     def method(self):
...         self.value += "1"
... 
>>> a = B()
>>> a.value
'str'
>>> a.method()
>>> a.value
'str1'
>>> b = B()
>>> b.value
'str'

I don't get, why list is shared but str is not?

like image 946
Rnd_d Avatar asked Apr 10 '12 08:04

Rnd_d


2 Answers

The value you are defining is not an instance field for your class, its more like a static field. But python doesn't mind if you access this field from instances. So, even if you access this field from instances, it is not a different list for each instance. Basically, you are appending to the same list every time the method is called.

You'll have to do this

class A(object):

    def __init__(self):
        self.value = []

    def method(self, new_value):
        self.value.append(new_value)

Now you have a different list created for each instance.

EDIT: Let me try to explain what happens when you use a str.

class A(object):

    self.value = 'str'

    def method(self):
        self.value += '1'

That last line in the previous code is the same as this:

        self.value = self.value + '1'

Now, this makes it abit easier to see what's going on. First, python gets the value from self.value. Since there is no instance field defined yet on self, this will give 'str'. Add '1' to that and sets it to the instance field called value. This is like

self.value = 'str1'

which is the same as you'd set an instance field in the __init__ method (in my first snippet of code).

self.value = []

Does that make it clear?

like image 192
sharat87 Avatar answered Sep 28 '22 16:09

sharat87


Define value in __init__(). There is no other way to define instance attributes.

Attributes bound outside a instance method are class attributes and shared by all instances of that class. Hence modifications of the objects bound to class attributes affect all instances of the class, as you've noticed in your example.

like image 45
lunaryorn Avatar answered Sep 28 '22 16:09

lunaryorn