11

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

  1. 我们创建一个foo带有 value 的变量bar

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

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

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

    >>> foo = 'spam'
    >>> baz
    'Hanging on in bar'
    

不应该是动态的吗?为什么会这样?我认为如果值发生foo变化,f-string 会更新,但这并没有发生。我不明白这是如何工作的。

4

2 回答 2

15

执行时f-string已经评估过:

>>> baz = f'Hanging on in {foo}'

具体来说,它查找名称的值foo并将其替换'bar'为为它找到的值。baz然后包含格式化后的字符串。

f-strings 不是常数;意思是,它们内部没有替换字段等待评估的评估。他们在您执行它们时进行评估,之后,分配的值只是一个普通的字符串

>>> type(f'hanging on in {foo}')
<class 'str'>

有关参考,请参阅格式化字符串文字部分

[..] 虽然其他字符串文字总是有一个常量值,但格式化字符串实际上是在运行时评估的表达式。[..]

在执行表达式(查找替换字段及其后续格式)后,它们没有什么特别之处,表达式已被评估为字符串并分配给baz.

于 2016-12-23T19:36:31.280 回答
1

字符串是不可变的,一旦创建了字符串,就不能再更改它。

foo更重要baz的是两个字符串。这意味着当您创建它们时,它们会进入内存并且无法再更改。

分配foo = bar后,您将创建此对象并将其分配到内存中的特定位置。同样的事情已经完成baz

即使baz是作为格式字符串文字并不意味着它不再是不可变的,因为:

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

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

创建后foo = 'spam',您会破坏原始分配foo并在内存中创建新分配。

于 2016-12-24T02:44:59.880 回答