pythonclass

Make property of python class dependent on external variable?


I'm relatively new to python, and am learning the class system. What I want to do is something like this:

foo = "1"
class test () :
    def __init__(self, name):
        self.name = foo
testVar = test (foo)
foo = "2"
print(testVar.name)
#return value: "1"
#wanted return value: "2"

Essentially what I want to do is have a property of a class that I can change when I want it too, so that I can define class properties as a variable and change that variable to change the properties of whole groups of variables of that type.


Solution

  • The way variables work is by storing values. Currently, foo stores the value "1", so whenever you use foo in an expression, you always get the value "1". However, with mutable data types, like objects or lists, variables store a reference to those values.

    Therefore, you could do something like this:

    foo = ["1"]
    class test():
        def __init__(self, name_ref):
            self._name = name_ref
        @property
        def name(self):
            return self._name[0]
    
    testVar = test(foo)
    foo[0] = "2"
    print(testVar.name)
    

    Note that this is a pretty hacky implementation, and a better one would involve creating a class to hold the data rather than using a list, like below:

    class ValueHolder():
        def __init__(self, value):
            self.value = value
    
    foo = ValueHolder("1")
    class test() :
        def __init__(self, name):
            self._name = name
        @property
        def name(self):
            return self._name.value
    
    testVar = test(foo)
    foo.value = "2"
    print(testVar.name)
    

    However, you will never be able to do foo = "2" and have it update, as Python (unlike C++ or other languages) provides no way to override the assignment operator -- that is, if you assign something to a name, you are essentially discarding the old value of that name, preventing foo = "2" from doing anything other than giving foo a new value of "2".