John Hon
John Hon

Reputation: 203

Why don't string variables update when they are changed

Say we have some code like so :

placehold = "6"
string1 = "this is string one and %s" % placehold

print string1

placehold = "7"
print string1

When run, both of the print statements return as if placehold were ALWAYS 6. However, just before the second statement ran, placehold was changed to 7, so why does it not dynamically reflect in the string?

Also, would you be able to suggest a way to make the string return with 7?

Thank you

Upvotes: 3

Views: 3968

Answers (4)

kindall
kindall

Reputation: 184260

Strings are immutable and can't be changed, but what you're trying to do doesn't work with mutable objects either, so mutability (or lack of it) is something of a red herring here.

The real reason is that Python does not work like Excel. Objects do not remember all the operations that have been performed on them, and then re-do those operations when you change any of the information that went into them. For Python to work that way, the language would need to retain either every state that every object had ever been in, or all the operations that had ever been performed on them along with their parameters. Either would make your programs use a lot more memory and run much more slowly. On top of that, suppose you used string1 in another expression: that value, too, would need to be updated. In Python 3, print() is a function; should it be called again when the variable printed is changed?

There are languages that work like that, to some extent, but Python isn't one of them. Unless you explicitly arrange things otherwise (by writing and calling a function), Python evaluates an expression once and uses that exact result going forward.

In fact, what you want isn't even possible in Python. When you do string interpolation (the % operation), the code that does it sees only the value of what you're interpolating. It doesn't know that the "6" is coming from a variable called placehold. Therefore it couldn't change the string later even if it wanted to, because there's no way for it to know that there's any relationship between placehold and string1. (Also, consider that you needn't be interpolating a single variable: it could be an expression such as placehold + "0". So Python would need to remember the entire expression, not just the variable name, to re-evaluate it later.)

You can write your own string subclass to provide the specific behavior you want:

class UpdatingString(str):
    def __str__(self):
        return self % placehold

placehold = "6"
string1 = UpdatingString("this is string one and %s")
print(string1)
placehold = "7"
print(string1)

But this is fraught with scoping issues (basically, the class needs to be able to see placehold, which means that variable and the class need to be defined in the same function or in the global scope). Also, if you use this special string in an operation with another string, say concatenation, it will almost certainly cease being special. To fix these issues is possible, but... hairy. I don't recommend it.

Upvotes: 2

Moinuddin Quadri
Moinuddin Quadri

Reputation: 48090

When you do:

string1 = "this is string one and %s" % placehold

You are creating a string string1 with %s replaced by the value of placehold On later changing the value of placehold it won't have any impact on string1 as string does not hold the dynamic property of variable. In order to reflect the string with changed value, you have to again re-assign the string.

Alternatively, you may use .format() as:

string1 = "this is string one and {}"
placeholder = 6
print string1.format(placeholder)
# prints: this is string one and 6

placeholder = 7
print string1.format(placeholder)
# prints: this is string one and 7

Upvotes: 7

imant
imant

Reputation: 627

Because you have already assigned a value to that variable once you execute the statement.

It sounds like you'd rather need a function such as:

def f(placehold):
    return "this is string one and %s" % placehold

Now you can print(f("7")) to achieve the desired functionality.

Upvotes: 4

pzp
pzp

Reputation: 6607

string1 will use whatever value of placehold existed at the time string1 was declared. In your example, that value happens to be "6". To get string1 to "return with 7" you would need to reassign it (string1 = "this is string one and %s" % placehold) after changing the value of placehold.

Upvotes: 1

Related Questions