-1

I'm facing strange issue with my code bellow. I simple cannot understand, why the simpleFiled attribute of myClass remain "prepoluated" from previous "round".

Code:

class myClass:
    simpleField = []
    name = ''

    def __init__(self,simple_field=[]):
         self.simpleField = simple_field
         print('In __init__ %s ' % str(simple_field))


    def __str__(self):
        return self.name

    def __repr__(self):
        return self.name+' '.join(str(self.simpleField))

def fill(name='default'):
    m = myClass()
    m.name = name
    for i in range(0,5):
        m.simpleField.append(i)
    return m

if __name__ == '__main__':
    for i in range(0,2):
        m = fill('round '+str(i))
        print(m.__repr__())

Output (I numbered lines for better understanding)

1. In __init__ []
2. round 0[ 0 ,   1 ,   2 ,   3 ,   4 ]
3. In __init__ [0, 1, 2, 3, 4]
4. round 1[ 0 ,   1 ,   2 ,   3 ,   4 ,   0 ,   1 ,   2 ,   3 ,   4 ]

Lines 1 and 2 are pretty obvious and no magic over here. I cannot understand why in line 3 I have received such a simple_field values. As I can see in my code I create the instance of the class without any arguments - m = myClass()

Thank you for any advice

Y

z4nD4R
  • 1
  • 1

2 Answers2

1
def print_with_extra(lst=[]):
    lst.append("extra")
    print(lst)

print_with_extra(["apple"])  # ['apple', 'extra']
print_with_extra() # ['extra']
print_with_extra() # ['extra', 'extra']

The default arguments to functions in Python evaluate once - when the function is defined.

Lists are mutable, and .append will change the instance it operates upon.

Therefore, instead of creating a new empty list, print_with_extra reuses a single default value initialized to an empty list once, and keeps all the appended elements from the results of default calls there.

The same is happening in your constructor.

Koterpillar
  • 7,883
  • 2
  • 25
  • 41
1

You're using a mutable Type (list) as standard value - it's created once upon definition of your function and remains the same instance on every call. Change it to be None and define it as [] in the function body if simple_field is None

SV-97
  • 431
  • 3
  • 15