Skip to content
Advertisement

Why does the self in the class always have the previous data?

im new to python and today i had this problem:

say, i have this code incluing two classes named: slice and mat:


class slice():
    def __init__(self, var:int) -> None:
        self.__var = var
    @property
    def var(self):
        return self.__var

class mat():
    __slices = []
    def __init__(self,var:list) -> None:
        self.__var = var
        for i in var:
            self.__slices.append(slice(i))
    @property
    def val(self):
        return self.__var
    @property
    def slices(self):
        return self.__slices

ori_data = [
    [1,2,3,4],
    [5,6,7,8]
]

list_mat = []
for i in ori_data:
    list_mat.append(mat(i))
print(len(list_mat))
for i in list_mat:
    print(i.slices)

output:

2
[<__main__.slice object at 0x000002B20597E908>, <__main__.slice object at 0x000002B205957FC8>, <__main__.slice object at 0x000002B2059C7588>, <__main__.slice object at 0x000002B2059C76C8>, <__main__.slice object at 0x000002B2059C7508>, <__main__.slice object at 0x000002B2059D3708>, <__main__.slice object at 0x000002B2059D37C8>, <__main__.slice object at 0x000002B2059D3808>]
[<__main__.slice object at 0x000002B20597E908>, <__main__.slice object at 0x000002B205957FC8>, <__main__.slice object at 0x000002B2059C7588>, <__main__.slice object at 0x000002B2059C76C8>, <__main__.slice object at 0x000002B2059C7508>, <__main__.slice object at 0x000002B2059D3708>, <__main__.slice object at 0x000002B2059D37C8>, <__main__.slice object at 0x000002B2059D3808>]

I thought that: the list_mat would have 2 mat object(which is true by the output of print(len(list_mat)))

And i thought every mat object in list_mat would have 4 slice objects and the var for each slice obj would be 1 2 3 4 and 5 6 7 8 for each mat obj.

But when it came to the actual mat object in the list_mat,every mat have 8 slice objects and they had the exactly same 8 slice objects in the memory.

When i debugged, i found that when i created the second mat object, in the __init__, the self already had previous value(which were the slices created for the first mat). So that when i passed the second list 5 6 7 8 for the constructor, it would just add another 4 slice objects for the second mat which gave me the result of 8 slice objects.

Another thing is when the second mat was created, the __slice in the first mat changed into the __slice in the second mat! Actually when i checked the __init__ function when debugged, i found that the address of the second mat‘s self object, it was the address of the first mat object which had beed created already.

There must be some deepcopy stuff i have missed.

So to sum:

1: during a for loop, the self obj for the mat class always has the previous data left by the creation of the first mat obj

2: during a for loop, how can i deepcopy and created a whole new obj with everything created new in the memory

Any advice would help!

let me know if you don’t understand my question!

Wishes!

Advertisement

Answer

@jasonharper had it right…..

class mat():
    __slices = []

This code creates a CLASS LEVEL variable which is shared by all instances of the class. This is useful for example, if you wanted to have a object_count variable which you increment during object creation and decrement during destruction. But, in your case, you want each mat object to have its own __slices, so you want to define that variable within __init__():

    def __init__(self,var:list) -> None:
        self.__var = var
        self.__slices = []

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement