Search code examples
pythonclassobjectinheritancemethods

Weird issue during calling the object's method in python - 'self' pointing to the wrong object?


I found some weird behaviour during the creation of classes and objects in python3.

I dislike typing every time "self" word and constructors during writing classes if my class is very simple so I made the class 'Foo' that copies static variables and turns them into the new object's attributes.

At the beginning I was making 'Foo' subclasses without methods and then everything worked fine - the objects were distinct. However, after adding a method to the subclass, I found out that the self value somehow points to wrong object.

Here is the code I made:

from copy import deepcopy


class Foo:
    def __init__(self):
        for i in filter(lambda x: "__" not in x, self.__dir__()):
            self.__setattr__(i, deepcopy(self.__getattribute__(i)))


class Bar(Foo):
    val = []

    def func(self):
        print("Self ID:", id(self))
        print(self.val)


obj = Bar()
obj.val.append(2)
print("Object ID:", id(obj))
print(obj.val)
obj.func()

# Prints:
#
# Object ID: 2507794284496
# [2]
# Self ID: 2507794283248
# []
#
# While it should print same ID and [2] in both lists

I am sure that I forgot something important during creation of the Foo class because if I remove "(Foo)" part then IDs and the lists are the same.

Could someone explain me what is wrong? Thank you in advance for help! <3


Solution

  • I disabled methods from copying and it seems working now. Here is the code:

    from copy import deepcopy
    
    
    class Foo:
        def __init__(self):
            for i in filter(lambda x: "__" not in x, self.__dir__()):
                attr = self.__getattribute__(i)
                if attr.__class__.__name__ != 'method':
                    self.__setattr__(i, deepcopy(attr))
    
    
    class Bar(Foo):
        val = []
    
        def func(self):
            print("Self ID:", id(self))
            print(self.val)
    
    
    obj = Bar()
    obj.val.append(2)
    print("Object ID:", id(obj))
    print(obj.val)
    obj.func()
    
    # Object ID: 2785572945632
    # [2]
    # Self ID: 2785572945632
    # [2]
    

    I don't see any usecase where copying the method would be necessary so it's not an issue really for me.

    Great thanks @user2357112 for explaining me what was not working <3