为什么f-strings在它们引用的变量发生变化时不会改变?

时间:2016-12-23 19:29:26

标签: python python-3.x python-3.6 f-string

在最近的Python 3.6版本中使用新的f字符串时,我注意到以下内容:

  1. 我们创建了一个值为foo的{​​{1}}变量:

    bar
  2. 然后,我们声明一个新变量,它是我们的f-string,它应该被>>> foo = 'bar' 格式化:

    foo
  3. 好的,一切正常,然后我们致电>>> baz = f'Hanging on in {foo}' 检查其值:

    baz
  4. 让我们尝试更改>>> baz 'Hanging on in bar' 的值并再次致电foo

    baz
  5. 它不应该是动态的吗?为什么会这样?我认为如果>>> foo = 'spam' >>> baz 'Hanging on in bar' 的值发生了变化,f字符串会更新,但这并没有发生。我不明白这是如何运作的。

2 个答案:

答案 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完成了同样的事情。

尽管bazFormat string literal相同并不意味着它不再是不可变的,因为:

In [4]: type(baz)
Out[4]: str

通过这样做,baz被创建为对象并作为Hanging on in bar分配给您的内存,因此它与foo的关系纯粹是在实例化期间。在此期间baz寻找对象foo并在适当的位置连接它。

创建foo = 'spam'后,您销毁 foo的原始作业,并在内存中创建一个新作品。