1
class Test:
    TheFlag = True
    StartNodeQuery = {1, 2, 3, 4, 5}

    def parsa(self):
        while self.TheFlag:
            SNQ = self.StartNodeQuery
            self.iterator(SNQ)

    def iterator(self, CurrentNodeQuery):

        #it prints {1, 2, 3, 4, 5}
        print(CurrentNodeQuery)


        if len(CurrentNodeQuery) < 100:
            b = len(CurrentNodeQuery) * 2
            c = len(CurrentNodeQuery) * 3
            self.StartNodeQuery.update({b, c})

            # it prints {1, 2, 3, 4, 5, 10, 15}
            print(CurrentNodeQuery)

        else:
            self.TheFlag = False

        assert 0

obj = Test()
obj.parsa()

as you can see I deliberately ended the program with assert 0. The Main issue is: Before the function is finished the parameters that is passed to it gets changed!

as you can see StartNodeQuery = {1, 2, 3, 4, 5} and SNQ = self.StartNodeQuery

so why when I change the size of the self.StartNodeQuery inside the function before it's finished , CurrentNodeQuery which is a different variable with the same values as self.StartNodeQuery (or SNQ) gets changed as well, even though we didn't pass the new self.StartNodeQuery to CurrentNodeQuery yet?

I hope you understand my problem, if you have the solution, please help a guy out

  • 1
    Parameter passing doesn't copy objects. See https://nedbatchelder.com/text/names.html – user2357112 May 19 '19 at 18:26
  • [Also you're making class variables instead of instance variables](https://stackoverflow.com/questions/1680528/how-to-avoid-having-class-data-shared-among-instances), but that's a different problem. – user2357112 May 19 '19 at 18:27

1 Answers1

0

Some issues and suggestions in your code

  • Don't mix class and instance variables. You are using class variables TheFlag and StartNodeQuery as instance variables, so make them one

  • Use a constructor to instantiate instance variables

  • Perhaps use exit() to break the function

  • You need to explicitly copy the set to make a new instance via copy.copy. Assignment SNQ = self.StartNodeQuery just makes a new reference to the variable

So the fixed code might look like

from copy import copy

class Test:

    def __init__(self):

        # Made instance variables as class variables
        self.TheFlag = True
        self.StartNodeQuery = {1, 2, 3, 4, 5}

    def parsa(self):

        while self.TheFlag:
            SNQ = self.StartNodeQuery.copy()
            self.iterator(SNQ)


    def iterator(self, CurrentNodeQuery):

        #it prints {1, 2, 3, 4, 5}
        print(CurrentNodeQuery)


        if len(CurrentNodeQuery) < 100:
            b = len(CurrentNodeQuery) * 2
            c = len(CurrentNodeQuery) * 3
            self.StartNodeQuery.update({b, c})

            # it prints {1, 2, 3, 4, 5, 10, 15}
            print(CurrentNodeQuery)

        else:
            self.TheFlag = False

        #Use exit to break the function
        exit()

obj = Test()
obj.parsa()

And the output will be

{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5}
Devesh Kumar Singh
  • 20,259
  • 5
  • 21
  • 40