Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

in python, When assigning a variable to self variable in a class its a pointer to the self variable?

In the example code below, i have a piece of code from a project. I have a self.test_json.test_id, which is an instance of a class being assigned by a json in the constructor, and in the function do_somthing(self) i want to assign a new variable var in the function scope to be equal to the self.test_json.test_id variable, without changing it.
but when i call to do_somthing(self), when i change the value of var the value of self.test_json.test_id changes aswell. why this is happening? as far as i know there is no pointers and references in python, shouldn’t the var create a copy of self.test_json.test_id ?

from types import SimpleNamespace
import json


class Test:
    def __init__(self, json_data):
        self.tests = json_data.tests
        self.test_json = ""
        
    def do_something(self):
        for test in self.tests:
            var = test.test_json
            self.test_json = var
            print("The self.test_json is: " + str(self.test_json.test_id))
            print("test_json is: " + str(var.test_id))
            var.test_id = 6
            print("(should be 5, unchanged) The self.test_json is: " + str(self.test_json.test_id))
            print("(should be 6, changed) test_json is: " + str(var.test_id))


if __name__ == '__main__':
    json_data = b'{"tests": [{"test_json": {"test_id":5 }}]}'
    data_as_simple_namespace = json.loads(json_data, object_hook=lambda d: SimpleNamespace(**d))
    t = Test(data_as_simple_namespace)
    t.do_something()

after the function is called, it will print:

The self.test_json is: 5
test_json is: 5
(should be 5, unchanged) The self.test_json is: 6
(should be 6, changed) test_json is: 6

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The self.test_json = var makes the self.test_json a reference to var, they are connected/referring to the same value/memory.

A quick fix could look this:

import copy  # HERE
import json

from types import SimpleNamespace


class Test:
    def __init__(self, json_data):
        self.tests = json_data.tests
        self.test_json = ""

    def do_something(self):
        for test in self.tests:
            var = test.test_json
            self.test_json = copy.copy(var)  # and HERE
            print("The self.test_json is: " + str(self.test_json.test_id))
            print("test_json is: " + str(var.test_id))
            var.test_id = 6
            print(
                "(should be 5, unchanged) The self.test_json is: "
                + str(self.test_json.test_id)
            )
            print("(should be 6, changed) test_json is: " + str(var.test_id))


if __name__ == "__main__":
    json_data = b'{"tests": [{"test_json": {"test_id":5 }}]}'
    data_as_simple_namespace = json.loads(
        json_data, object_hook=lambda d: SimpleNamespace(**d)
    )
    t = Test(data_as_simple_namespace)
    t.do_something()
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading