0

I'm trying to change self.var_1 in the code below from another class, but I receive the error test1 has no attribute 'var_1'. I feel like I'm making a simple mistake but can't seem to find the issue.

class test1:
    def __init__(self):
        self.var_1 = "bob"
        instance2 = test2()

    def change_var(self, new_var):
        print(self.var_1) #should print "bob"
        self.var_1 = new_var #should change "bob" to "john"
        print(self.var_1) #should print "john"

class test2:
    def __init__(self):
        test1.change_var(test1, "john")

instance = test1()
Matt
  • 964
  • 11
  • 30
  • @SunnyPatel, doesn't work, yields error `change_var() missing 1 required positional argument: 'new_var'` – Matt Jul 17 '18 at 21:39
  • No. That would not follow proper [OOD](https://en.wikipedia.org/wiki/Object-oriented_design). You could instantiate `test1` inside `test2` and call `instance.change_var` there. – Sunny Patel Jul 17 '18 at 21:39
  • @SunnyPatel that sounds like a messy solution, I'm using this in a GUI and instantiating Test1 twice would open a bunch of random frames. – Matt Jul 17 '18 at 21:42
  • You should probably implement a [Singleton Pattern](https://www.google.com/search?q=python+singleton) if you are wanting to have only one instance of it. – Sunny Patel Jul 17 '18 at 21:44

2 Answers2

3

var_1 is an instance variable, so you need to use the instance:

class test1:
    def __init__(self):
        self.var_1 = "bob"
        instance2 = test2(self)    # <<<<<< pass test1 instance

    def change_var(self, new_var):
        print(self.var_1) #should print "bob"
        self.var_1 = new_var #should change "bob" to "john"
        print(self.var_1) #should print "john"

class test2:
    def __init__(self, t1obj):      # <<<< take test1 instance
        t1obj.change_var("john")    # <<<< use test1 instance

instance = test1()

Gives:

bob
john
cdarke
  • 37,606
  • 5
  • 69
  • 77
1

Based on your comments, I feel like you are looking to create a singleton pattern for your class.

There are multiple ways to accomplish this, most of which can be found in the above SO question.

I made one that uses the first method outlined in the top answer by creating a decorator, and applying it to your class.

def singleton(class_):
    instances = {}
    def getinstance(*args, **kwargs):
        if class_ not in instances:
            instances[class_] = class_(*args, **kwargs)
        return instances[class_]
    return getinstance

@singleton
class Test1(object):
    def __init__(self):
        self.var_1 = "bob"

    def change_var(self, new_var):
        print(self.var_1) #should print "bob"
        self.var_1 = new_var #should change "bob" to "john"
        print(self.var_1) #should print "john"

class Test2(object):
    def __init__(self):
        test1 = Test1()
        test1.change_var("john")

Test2()

You can view this on repl.it and see the results match your output.

bob

john

Community
  • 1
  • 1
Sunny Patel
  • 7,143
  • 2
  • 28
  • 41