Search code examples
pythonclassself

Two versions of self object within class, how can this be?


I have been experimenting with a class that contains functions returning a generated class.

I want the generated class to have the 'self' object. It gets all attributes within self so I assigned 'self' to the generated self variable which I named 'own' to reduce confusion.

When assigning 'own' to 'self' python creates a second version of own and gives it a different id. When calling the function the old 'own' gets returned.

import copy
from pprint import pprint


class test_class1(object):
    def __init__(self, number):
        self.number=number
        self.abc=['a','b','c']

    def test_class2(self):
        class test_class(object):
            def __init__(own):
                print('own id:')
                pprint(id(own))
                print('own attributes:')
                pprint(own.__dict__)
                print('\n')

                own=copy.deepcopy(self)
                print('own has selfs attributes own.number:',own.number)
                print('own id:')
                pprint(id(own))
                print('own attributes:')
                pprint(own.__dict__)
                print('\n')

        return test_class

a=test_class1(7).test_class2()()
print('own has no attributes anymore')
print('own id:')
pprint(id(a))
print('own attributes:')
pprint(a.__dict__)
print('\n')

The output is:

own id:
140178274834248
own attributes:
{}


own has selfs attributes own.number: 7
own id:
140178274834584
own attributes:
{'abc': ['a', 'b', 'c'], 'number': 7}


own has no attributes anymore
own id:
140178274834248
own attributes:
{}

I have found a workaround but can someone explain why there are two versions of 'own' with different IDs and how I can only have one?


Solution

  • I think you need to replace own=copy.deepcopy(self) with own.__dict__.update(self.__dict__). It will not change id(own) but will give all attributes of self to copied own object.

    Code:

    import copy
    from pprint import pprint
    
    
    class test_class1(object):
        def __init__(self, number):
            self.number=number
            self.abc=['a','b','c']
    
        def test_class2(self):
            class test_class(object):
                def __init__(own):
                    print('own id:')
                    pprint(id(own))
                    print('own attributes:')
                    pprint(own.__dict__)
                    print('\n')
    
                    own.__dict__.update(self.__dict__)  # here is the change
                    print('own has selfs attributes own.number:',own.number)
                    print('own id:')
                    pprint(id(own))
                    print('own attributes:')
                    pprint(own.__dict__)
                    print('\n')
    
            return test_class
    
    a=test_class1(7).test_class2()()
    print('own still has attributes')
    print('own id:')
    pprint(id(a))
    print('own attributes:')
    pprint(a.__dict__)
    print('\n')
    

    Output:

    own id:
    140228632050376
    own attributes:
    {}
    
    
    own has selfs attributes own.number: 7
    own id:
    140228632050376
    own attributes:
    {'abc': ['a', 'b', 'c'], 'number': 7}
    
    
    own still has attributes
    own id:
    140228632050376
    own attributes:
    {'abc': ['a', 'b', 'c'], 'number': 7}