Python Forum
Instances sharing attributes - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Instances sharing attributes (/thread-21220.html)



Instances sharing attributes - midarq - Sep-19-2019

Hello,

I have the following problem:
Why is the instance B updating and how do i prevent that?
class myclass():

    def __init__(self, x=[]):
        self.x = x

    def append_to(self):
        self.x.append('foo')
A=myclass()
B=myclass()
A.append_to()
B.x
This returns ['foo'].

Thank you for your help


RE: Instances sharing attributes - ichabod801 - Sep-19-2019

You are using a list as a default. Defaults are evaluated once and stored, not evaluated each time you call the method. Since lists are mutable, self.x becomes a pointer to that list, not a copy of that list. That makes every instance share the same self.x, unless x is passed explicitly. You generally solve this with a default of None:

class myclass():
 
    def __init__(self, x=None):
        if x is None:
            self.x = []
        else:
            self.x = x



RE: Instances sharing attributes - midarq - Sep-20-2019

Thank you for your solution. I wonder however if there is a more elegant way of achieving the same results. My code so far looks like this:
class my_data():
    def __init__(self, mn=None, r=None, x=None, y=None):
        if x is None:
            self.x=[]
        else:
            self.x = x
        if y is None:
            self.y=[]
        else:
            self.y = y
        if mn is None:
            self.mn=[]
        else:
            self.mn = mn
        if r is None:
            self.r=[]
        else:
            self.r= r
Thank you in advance


RE: Instances sharing attributes - perfringo - Sep-20-2019

You can take advantage of Python 'returning operand' feature:

>>> scale = None
>>> scale = scale or None
>>> print(scale)
None
>>> scale = 10
>>> scale = scale or None
>>> scale
10



RE: Instances sharing attributes - midarq - Sep-20-2019

This is much more compact! Thanks!

class my_data():    
    def __init__(self, mn=None, r=None, x=None, y=None):
        self.x  = x or []
        self.y  = y or []
        self.mn = mn or []
        self.r  = r or []