【问题标题】:Why don't f-strings change when variables they reference change?为什么当它们引用的变量发生变化时,f-strings 不会发生变化?
【发布时间】:2017-05-09 11:35:41
【问题描述】:

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

  1. 我们创建一个foo 变量,其值为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 会更新,但这并没有发生。我不明白这是怎么回事。

【问题讨论】:

  • 您希望表达式'Hanging on in ' + foo 表现如何?
  • 'hanging on in {}'.format(foo) - 他们保留对插值的引用。
  • 据我了解,这些花哨的“f-strings”只是str.format 的某种语法糖。
  • @JoshLee 一个更好的问题是他们期望foo = f'{foo}' 的行为方式。

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


【解决方案1】:

f-string 在您执行时已经被评估:

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

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

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

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

参考见the section on Formatted String Literals:

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

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

【讨论】:

  • baz创建后是什么?一个普通的字符串?还是它有一些特殊的f 属性?
  • @hpaulj type(baz) 会告诉你;普通字符串。
【解决方案2】:

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

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的原始分配并在内存中创建一个新的。

【讨论】:

    猜你喜欢
    • 2022-11-26
    • 2014-05-16
    • 1970-01-01
    • 2022-07-29
    • 2015-09-14
    • 2015-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多