3

I have following code block.

class Starter():
    def __init__(self, reference):
        self.reference = reference

    def change_ref(self):
        print("Got :", self.reference)
        self.reference = 1
        print("Now :", self.reference)

class Stopper():
    def __init__(self, reference):
        self.reference = reference

    def change_ref(self):
        print("Got :", self.reference)
        self.reference = 2
        print("Now :", self.reference)


class Controller():

    def __init__(self):
        self.main_reference = 0
        self.starter = Starter(self.main_reference)
        self.stopper = Stopper(self.main_reference)

controller = Controller()
controller.starter.change_ref()
controller.stopper.change_ref()

and it outputs the following :

Got : 0
Now : 1
Got : 0
Now : 2

I want the starter and stopper class to modify and reach to same object. So the output I am looking is the following :

Got : 0
Now : 1
Got : 1
Now : 2

What is the best way to do this with using three different classes? Rather than array usage I am curious if we can take advantage of classes. If possible I can also use nested classes. My only constraint is that Starter and Stopper classes must be separated from each other since in my project I am using them as QThread subclasses. Which leads them to override their run method in a different way.

martineau
  • 119,623
  • 25
  • 170
  • 301
I.K.
  • 414
  • 6
  • 18
  • Possible duplicate of [How do I pass a variable by reference?](https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference) – dangee1705 Oct 23 '19 at 14:39
  • Thank you so much for answer, I was aware of the link you shared. But as I mentioned in the question I am looking for a solution that takes advantage of class usage. I stated that I want to use nested class if possible. So this question may differ in answer with the one you shared. But thanks! – I.K. Oct 23 '19 at 14:43
  • Doing this with three separate classes seems unnecessarily complicated. What's keeping you from having a single class, with `.start()` and `.stop()` methods that access a single instance variable, so you don't actually need to share references to anything? Keep in mind that you can refer to a bound method of an instance - for example, `starter = controller.start`, and later call `starter()`. – jasonharper Oct 23 '19 at 14:44
  • The code block I shared is a brief summary of my actual work. In my project starter and stopper classes are subclass of QT's QThread. Hence they override the run method and should be kept in different classes in my understanding. – I.K. Oct 23 '19 at 14:47

2 Answers2

4

Not sure it is the most elegant approach but using a list as reference do the job:

class Starter():
    def __init__(self, reference):
        self.reference = reference

    def change_ref(self):
        print("Got :", self.reference[0])
        self.reference[0] = 1
        print("Now :", self.reference[0])

class Stopper():
    def __init__(self, reference):
        self.reference = reference

    def change_ref(self):
        print("Got :", self.reference[0])
        self.reference[0] = 2
        print("Now :", self.reference[0])


class Controller():

    def __init__(self):
        self.main_reference = [0]
        self.starter = Starter(self.main_reference)
        self.stopper = Stopper(self.main_reference)

controller = Controller()
controller.starter.change_ref()
controller.stopper.change_ref()
SPH
  • 478
  • 2
  • 6
3

Your example does not work since when you instantiate the Starter and Stopper classes you pass them an integer, and it is passed by value.

In order to make this work, an option is to pass the controller object itself to the Starter and Stopper constructors, so that they can access and modify its main_reference:

class Starter():
    def __init__(self, controller):
        self.controller = controller

    def change_ref(self):
        print("Got :", self.controller.main_reference)
        self.controller.main_reference = 1
        print("Now :", self.controller.main_reference)

class Stopper():
    def __init__(self, controller):
        self.controller = controller

    def change_ref(self):
        print("Got :", self.controller.main_reference)
        self.controller.main_reference = 2
        print("Now :", self.controller.main_reference)


class Controller():

    def __init__(self):
        self.main_reference = 0
        self.starter = Starter(self)
        self.stopper = Stopper(self)

controller = Controller()
controller.starter.change_ref()
controller.stopper.change_ref()
carlesgg97
  • 4,184
  • 1
  • 8
  • 24