在最近的Python 3.6版本中使用新的f字符串时,我注意到以下内容:
我们创建了一个值为foo
的{{1}}变量:
bar
然后,我们声明一个新变量,它是我们的f-string,它应该被>>> foo = 'bar'
格式化:
foo
好的,一切正常,然后我们致电>>> baz = f'Hanging on in {foo}'
检查其值:
baz
让我们尝试更改>>> baz
'Hanging on in bar'
的值并再次致电foo
:
baz
它不应该是动态的吗?为什么会这样?我认为如果>>> foo = 'spam'
>>> baz
'Hanging on in bar'
的值发生了变化,f字符串会更新,但这并没有发生。我不明白这是如何运作的。
答案 0 :(得分:13)
执行时f-string
已经评估
>>> baz = f'Hanging on in {foo}'
具体来说,它会查找名称foo
的值,并将其替换为'bar'
,即为其找到的值。 baz
然后包含格式化后的字符串。
f-string
不是常数;意思是,在评估之后,他们内部没有替换字段等待评估。 他们在执行时评估,之后,指定的值只是普通字符串:
>>> type(f'hanging on in {foo}')
<class 'str'>
供参考,请参阅the section on Formatted String Literals:
[..]虽然其他字符串文字总是有一个常量值,但格式化的字符串实际上是在运行时评估的表达式。 [..]
在执行表达式(替换字段的查找及其后续格式化)之后,对它们没有什么特别之处,表达式已经被计算为字符串并分配给baz
。
答案 1 :(得分:0)
字符串是不可变的,一旦创建了字符串,就不能再更改它了。
foo
更重要的是baz
都是字符串。这意味着当你创建它们时,它们会进入内存而不能再被更改。
分配foo = bar
后,您创建了此对象并将其分配给内存中的特定位置。使用baz
完成了同样的事情。
尽管baz
与Format string literal相同并不意味着它不再是不可变的,因为:
In [4]: type(baz)
Out[4]: str
通过这样做,baz
被创建为对象并作为Hanging on in bar
分配给您的内存,因此它与foo
的关系纯粹是在实例化期间。在此期间baz
寻找对象foo
并在适当的位置连接它。
创建foo = 'spam'
后,您销毁 foo
的原始作业,并在内存中创建一个新作品。