1

I was working with two instances of a python class when I realize they where using the same values. I think I have a missunderestanding of what classes are used for.

A much simpler example:

class C():
 def __init__(self,err = []):
 
 self.err = err
 
 def add(self):
 
 self.err.append(0)
 
a = C()
print(a.err) # [] 
a.add()
print(a.err) # [0]
 
b = C()
print(b.err) # [0]
b.add()
print(a.err) # [0,0]
print(b.err) # [0,0] 

I don't underestand why b.err starts as [0] instead of []. And why when adding an element to b it affects a too.

asked Oct 7, 2021 at 6:36
2
  • don't do err = [] Commented Oct 7, 2021 at 6:37
  • There's only one list, which both objects (instances) will save a reference to. Commented Oct 7, 2021 at 6:40

3 Answers 3

1

The reason is here:

def __init__(self,err = []): default err value is saved inside class C. But err itself is mutable, so every time you append anything to it, next time it will have stored value and this default err value is saved as a.err and b.err:

a = C()
print(a.err) # a.err is err ([]) 
a.add()
print(a.err) # err is [0]
 
b = C()
print(b.err) # reused err that is [0]
b.add() # err is [0, 0]
print(a.err) # [0,0]
print(b.err) # [0,0] 

So basically err inside a and b is the same

Article: https://florimond.dev/en/posts/2018/08/python-mutable-defaults-are-the-source-of-all-evil/

answered Oct 7, 2021 at 6:40
Sign up to request clarification or add additional context in comments.

1 Comment

I thought the err = [] part reassigned a new list. It looks like I was brong. Thanks
1

I recommend that you check the Python core language features first. Check the official FAQs for Python 3, particularly https://docs.python.org/3/faq/programming.html#why-are-default-values-shared-between-objects is what you are looking for.

According to the recommendations, you have to change your code like so

from typing import List
class C():
 def __init__(self,err: List = None):
 self.err = [] if err is None else err
 
 def add(self):
 self.err.append(0)
a = C()
print(a.err) # [] 
a.add()
print(a.err) # [0]
 
b = C()
print(b.err) # []
b.add()
print(a.err) # [0]
print(b.err) # [0] 

I will also link to the concept of mutability in the docs as it seems that this was the issue for OP: https://docs.python.org/3/glossary.html#term-mutable

answered Oct 7, 2021 at 6:45

Comments

0

In here we want to identify a list is a mutable data structure in python. It is means we can change it as we want. Class is a blueprint of the object so after creating the object it should be working individually<- this is your question. yeah typically it is correct but in here thing is when we don't give the default value for after constructor parameters. It changes after we create an object. we want to determine the concept correctly.

code review given below,

a = C()
print(a.err) # [] #empty err list 
a.add()
print(a.err) # append 0 into err list
b = C()
print(b.err) # after create object that create a showing you in here
b.add() #aappend another 0 to err list
print(a.err) # [0,0] #err list
print(b.err) # [0,0] #err list
answered Oct 7, 2021 at 9:04

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.