-2

In the __init__ function of a class I initialize some variables in order to make them available throughout my class and other classes. These variables are given a value at a later stage in a function of a different class. But whenever they are set their identity changes. Since I have been passing around the references to these variables I don't want their identity to change.

I have already tried copy.copy() and copy.deepcopy(), but this also changes the identity of the variables.

The code below describes the situation in a simple way:

class MyObject:
    def __init__(self):
        self.name = 'test_object'
    def set_name(self, name):
        self.name = name

class MyClass:
    def __init__(self):
        self.my_object = MyObject()

def create_object():
    new_object = MyObject()
    new_object.set_name('new_object')
    print(f'Address of new object in function: {id(new_object)}')
    return new_object

if __name__ == '__main__':
    my_class = MyClass()

    print(f'Identity when variable has only be initialized: {id(my_class.my_object)}')

    my_class.my_object = create_object()

    print(f'Identity after the create has been called: {id(my_class.my_object)}')

The code above produces the following output:

Identity when variable has only be initialized: 87379952
Address of new object in function: 87425104
Identity after the create has been called: 87425104

What I would like to have is that the identity of my_class.my_object stays the same and does not change to the identity of the object created in the function. Would someone know how to achieve this?

martineau
  • 119,623
  • 25
  • 170
  • 301
Enzo
  • 81
  • 7
  • 4
    The whole *point* of object identity is to distinguish two objects that are otherwise *equivalent*. You cannot copy identities, because then separate objects would not have unique identities. – chepner May 13 '19 at 13:29
  • You are misusing identities if you require that `copy` preserve the identity. – chepner May 13 '19 at 13:29
  • It looks like you want `MyObject` to be a singleton. – mkrieger1 May 13 '19 at 13:37
  • 1
    Possible duplicate of [Creating a singleton in Python](https://stackoverflow.com/questions/6760685/creating-a-singleton-in-python) – mkrieger1 May 13 '19 at 13:38
  • 3
    _why_ are you attempting to do this? this smells of the XY problem. – xrisk May 13 '19 at 13:40
  • Presumably you are using CPython, in which case [the identity returns the memory address](https://docs.python.org/3/library/functions.html#id) at which the object is stored. If you aim to keep those addresses the _same_, you should not make a new object: create it once, and return a reference on subsequent invocations. This is known as a Singleton, as others have remarked above. – Nelewout May 13 '19 at 13:41
  • In CPython, an object's identity **is** its memory address. – martineau May 13 '19 at 13:41
  • @mkrieger1 There could be multiple instances of the class, so it shouldn't be a singleton. – Enzo May 13 '19 at 14:02
  • @Rishav I want to do this, because before giving the right values to the class 'my_object' I need to have it's reference. – Enzo May 13 '19 at 14:04
  • Considering your comments, it would be better to: pass the object to the function create_object(), and modify the object accordingly instead of creating a complete different object? – Enzo May 13 '19 at 14:07

1 Answers1

0

Instead of creating a new instance of MyObject when initializing an instance of MyClass, you can explicitly pass a reference to an existing MyObject instance:

class MyObject:
    def __init__(self):
        self.name = 'test_object'
    def set_name(self, name):
        self.name = name

class MyClass:
    def __init__(self, my_object):
        self.my_object = my_object

def create_object():
    new_object = MyObject()
    new_object.set_name('new_object')
    print('Address of new object in function:', id(new_object))
    return new_object

if __name__ == '__main__':
    my_object = create_object()

    print('Identity after the create has been called:', id(my_object))

    my_class = MyClass(my_object)

    print('Identity when my_class has been initialized:', id(my_class.my_object))

Output:

Address of new object in function: 140518937186936
Identity after the create has been called: 140518937186936
Identity when my_class has been initialized: 140518937186936
mkrieger1
  • 19,194
  • 5
  • 54
  • 65