While playing with new f-strings in the recent Python 3.6 release, I\'ve noticed the following:
We create a foo
variable with value bar
The f-string
has already been evaluated when you executed:
>>> baz = f'Hanging on in {foo}'
Specifically, it looked up the value for the name foo
and replaced it with 'bar'
, the value that was found for it. baz
then contains the string after it has been formatted.
f-string
s aren't constant; meaning, they don't have a replacement field inside them waiting for evaluation after being evaluated. They evaluate when you execute them, after that, the assigned value is just a normal string:
>>> type(f'hanging on in {foo}')
<class 'str'>
For reference, see the section on Formatted String Literals:
[..] While other string literals always have a constant value, formatted strings are really expressions evaluated at run time. [..]
After the expression (the look-up for the replacement field and its consequent formatting) is performed, there's nothing special about them, the expression has been evaluated to a string and assigned to baz
.
Strings are immutable and once a string is created, it can no longer be changed.
foo
and more importantly baz
are both strings. That means when you create them they go into memory and can no longer be changed.
Once you assigned foo = bar
you created this object and assigned it to a specific location in memory. Same thing was done with baz
.
Even though baz
was as a Format string literal does not mean that it is no longer immutable since:
In [4]: type(baz)
Out[4]: str
By doing so, baz
was created as an object and assigned to your memory as Hanging on in bar
, thus its relation to foo
is purely during instantiation. During which baz
seeks the object foo
and concatenate it where appropriate.
Once you created foo = 'spam'
you destroyed the original assignment of foo
and create a new one in memory.