2

I have a Python 3 program with a hierarchy of classes that are all ultimately derived from a single base class 'RootClass'. I want to be able to set a value from an object of any of the classes and see that value from any other object of those classes. My current solution, which works, uses a global variable that is accessed by object methods defined in 'RootClass'.

file1.py:

_myVal= None  # the global variable

class RootClass:
    def setVal(self, y):
        global _myVal
        _myVal= y
    def getVal(self):
        return _myVal

file2.py:

from file1 import RootClass

class A (RootClass):
    pass
class B (A):
    pass
class C (B):
    pass
class D (RootClass):
    pass

if __name__ == "__main__":
    objA = A()
    objB = B()
    objC = C()
    objD = D()
    objD.setVal(100)
    print(objA.getVal())
    print(objB.getVal())
    print(objC.getVal())
    print(objD.getVal())

Executing:

CMD> python file2.py
100
100
100
100

I realize globals are generally frowned upon, but nothing else I've considered seems quite as clean and simple.

Another option I considered is making a 'ValClass' object that has set/get methods. Then the set/get methods in RootClass would call that object's set/get methods. But that means I have to still create the ValClass object, and make sure it's accessible from all other objects, so I'm basically back to having a global.

What is a better/more Pythonic way of solving this?

0

2 Answers 2

1

Just need to set the scope to the class's scope for _myVal

class RootClass:
    def setVal(self, y):
        RootClass._myVal= y #Changed _myVal to be in RootClass's scope
    def getVal(self):
        return RootClass._myVal


class A (RootClass):
    pass
class B (A):
    pass
class C (B):
    pass
class D (RootClass):
    pass

if __name__ == "__main__":
    objA = A()
    objB = B()
    objC = C()
    objD = D()
    objD.setVal(100)
    print(objA.getVal())
    print(objB.getVal())
    print(objC.getVal())
    print(objD.getVal())
Sign up to request clarification or add additional context in comments.

1 Comment

Well, that is just as simple as my solution and avoids globals. I'm embarrassed I didn't think of that. Thank you!
1

If you want it to look more pythonic, you can use properties:

class RootClass:  
    @property
    def val(self):
        return RootClass._myVal
    @val.setter
    def val(self, y):
        RootClass._myVal= y 

class A (RootClass):
    pass
class B (A):
    pass
class C (B):
    pass
class D (RootClass):
    pass

if __name__ == "__main__":
    objA = A()
    objB = B()
    objC = C()
    objD = D()
    objD.val = 100
    print(objA.val)
    print(objB.val)
    print(objC.val)
    print(objD.val)

1 Comment

I just looked up how properties work to understand your code. Now that I do, I can see how properties will be useful to me in other situations. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.