1

I would like to have a variable which is updated every time it is accessed relative to other variables it is composed of like:

string1 = "a"
string2 = "b" 
string3 = string1 + string2

print(string3)

gives ab

string1 = "c"

print(string3) 

gives cb

Is there a simple way in Python to achieve that?

9
  • 1
    Don't think so. It's a weird behaviour. Don't think I've came across this behaviour in any other programming language as well. If you really want such a thing, you'll need to implement a custom class for it. Commented Aug 14, 2019 at 14:49
  • 1
    With these primitive immutable objects, this is impossible. How "complex" is this allowed to get to achieve this result…? Commented Aug 14, 2019 at 14:49
  • 3
    You could wrap it in a function, then call the function when you want the updated value. Having stuff change behind the scenes isn't really ideal. It hides what's effecting what. This would make your program very confusing if you abused it too heavily. Commented Aug 14, 2019 at 14:51
  • The simpler the better - thought maybe someone has already implemented it in a library or something. If I can use even a complicated object implemented by somebody else it is okay this is not a HPC computation. Any advice will be highly appreciated. Commented Aug 14, 2019 at 14:51
  • 1
    @Revist Honestly, I don't know what "hyperparameters", so I can't speak for your particular case. I stand by just relying on a function call though. It's the built-in, commonly used mechanism to achieve what you're going for. The only difference is it requires a () call, which makes it clear when exactly data changed and where the changed data came from. Commented Aug 14, 2019 at 14:56

3 Answers 3

2

I am unaware if there's a better way to do this, or if you know this method, but asking for something better, but you can try this:

string1 = "a"
string2 = "b"
string3 = lambda:string1 + string2
print(string3())
>>> 'ab'
string1 = "c"
print(string3())
>>> 'cb'
Sign up to request clarification or add additional context in comments.

1 Comment

That is an even simpler solution. Thank you.
2

a = b will never mutate what was in a before; it will bind the name a to a new value. Nothing else will be affected by this, since anything can only reference the value, not the name. So what you need is a mutable value; anything that holds a reference to that mutable object will see any mutations on it:

class Foo:
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return self.value

class Bar:
    def __init__(self, *values):
        self.values = values

    def __str__(self):
        return ''.join(map(str, self.values))

string1 = Foo('a')
string2 = Foo('b')
string3 = Bar(string1, string2)

print(string3)

string1.value = 'c'

print(string3)

Comments

2

Depending on what exactly you need this for, you might also consider using custom class with a property - all values would be then contained in a single class, not as many objects (in case of many objects, string1=something mistyped instead of string1.value=something breaks your relation because it's not longer the same object).

You can access the property just like a normal member of the class (without parentheses) but its result may be dependent on other values (because behind the scenes, it's still a function).

class Test:
    def __init__(self, string1, string2):
        self.string1 = string1
        self.string2 = string2
    @property
    def string3(self):
        return self.string1 + self.string2

Example of usage:

>>> test = Test("a","b")
>>> print(test.string1, test.string2, test.string3)
a b ab
>>> test.string1 = "c"
>>> print(test.string1, test.string2, test.string3)
c b cb

2 Comments

Yes, this is in fact exactly what I wanted as I have everything contained within a class. The answer by @Sayandip Dutta, however, answers the posed (imprecisely) question best. Thank you !
Sure thing. I'm glad my mind-reading techniques worked. ;) (I.e. that I actually understood what you wanted.) I use properties for things that might be a members of the class but they are easily derived from other fields - so I don't have to worry about data consistency. Or I use them for wrapper classes, where I have e.g. some dict loaded from json for which need to keep the whole data (to use later), but I want to get properties for easy access of things I need now.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.