-1

I was trying to create class method, a list of next class object.

class main:
    a=[]
    def __init__(self):
        self.a.append(1)
        self.a.append(1)
class sub:
    b=[]
    def __init__(self):
        self.b.append(main())
        self.b.append(main())
obj=sub()
print(len(obj.b[0].a))

Shows output of 4

Should not the output be 2 as I am appending two values in a[] each time?

Add: Got to know why it shows output 4 instead of 2 but I am trying to create separate list a[] for every time constructor is called. i.e. someways output shall be 2.

quamrana
  • 37,849
  • 12
  • 53
  • 71
Anjaan
  • 1
  • 3

2 Answers2

1

When you do obj = sub() it initializes and self.b.append(main()) runs twice since it's written twice. Each time main() is initialized it appends 1 to a twice, that's why it has a length of 4

MichaelT572
  • 178
  • 1
  • 9
0

You should be careful while using mutable objects as class attributes. Class attributes will be shared by all of its objects.

If the class attribute is immutable(int, float, bool, string, unicode, tuple etc) then there is no problem because if an object tries to update it then it will create a new object itself as immutable objects cannot be updated.

But if mutable (list, dict, set etc) is used it will update the original memory address. This causes the problem.

Here's a demo:

1.mutable class attribute

class mutable():
    lst = []
    def __init__(self):
        self.lst.append(1)
        print('id:', id(self.lst))


obj1 = mutable()
obj2 = mutable()
obj3 = mutable()

print("list contains:", obj3.lst)


>>> id(mutable.lst)
2377975176712
>>> obj1 = mutable()
id: 2377975176712
>>> obj2 = mutable()
id: 2377975176712
>>> obj3 = mutable()
id: 2377975176712
>>>
>>> print("list contains:", obj3.lst)
list contains: [1, 1, 1]

2. immutable class attribute

class immutable():
    const = 10
    def __init__(self):
        pass

obj1 = immutable()
obj2 = immutable()


>>> obj1.const
10
>>> id(obj1.const)
140718539904096
>>>
>>> obj2 = immutable()
>>> obj2.const = 1
>>> obj2.const
1
>>> id(obj2.const)
140718539903808
>>> obj1.const
10
>>> obj2.const

(id prints memory location)

So in your code: the same list a will be updated at every init call and appends 1 twice. And 2 objects of main() are initialized hence the content of a will be [1, 1, 1, 1].

Girish Hegde
  • 1,420
  • 6
  • 16