为什么 f-strings 在它们引用的变量发生变化时不发生变化?
Why don't f-strings change when variables they reference change?
在最近的 Python 3.6 版本中演奏新的 f 弦时,我注意到以下几点:
我们创建一个 foo
变量,值为 bar
:
>>> foo = 'bar'
然后,我们声明一个新的变量,就是我们的f-string,格式化需要foo
:
>>> baz = f'Hanging on in {foo}'
好的,一切正常,然后我们调用 baz
来检查它的值:
>>> baz
'Hanging on in bar'
让我们尝试更改foo
的值并再次调用baz
:
>>> foo = 'spam'
>>> baz
'Hanging on in bar'
不应该是动态的吗?为什么会这样?我认为如果 foo
的值发生变化,f 字符串会更新,但这并没有发生。我不明白这是怎么回事。
f-string
在您执行时 已经 求值:
>>> baz = f'Hanging on in {foo}'
具体来说,它查找了名称 foo
的值并将其替换为 'bar'
,即为其找到的值。 baz
然后包含格式化后的字符串。
f-string
s 不是常数;意思是,它们内部没有等待评估 after 的替换字段。 当你执行它们时它们会计算,之后,分配的值是只是一个普通的字符串:
>>> type(f'hanging on in {foo}')
<class 'str'>
参考资料见the section on Formatted String Literals:
[..] While other string literals always have a constant value, formatted strings are really expressions evaluated at run time. [..]
执行表达式(查找替换字段及其后续格式化)后,它们没有什么特别之处,表达式已被评估为字符串并分配给 baz
。
字符串是不可变的,字符串一旦创建,就不能再更改。
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
的原始分配并在内存中创建了一个新分配。
在最近的 Python 3.6 版本中演奏新的 f 弦时,我注意到以下几点:
我们创建一个
foo
变量,值为bar
:>>> foo = 'bar'
然后,我们声明一个新的变量,就是我们的f-string,格式化需要
foo
:>>> baz = f'Hanging on in {foo}'
好的,一切正常,然后我们调用
baz
来检查它的值:>>> baz 'Hanging on in bar'
让我们尝试更改
foo
的值并再次调用baz
:>>> foo = 'spam' >>> baz 'Hanging on in bar'
不应该是动态的吗?为什么会这样?我认为如果 foo
的值发生变化,f 字符串会更新,但这并没有发生。我不明白这是怎么回事。
f-string
在您执行时 已经 求值:
>>> baz = f'Hanging on in {foo}'
具体来说,它查找了名称 foo
的值并将其替换为 'bar'
,即为其找到的值。 baz
然后包含格式化后的字符串。
f-string
s 不是常数;意思是,它们内部没有等待评估 after 的替换字段。 当你执行它们时它们会计算,之后,分配的值是只是一个普通的字符串:
>>> type(f'hanging on in {foo}')
<class 'str'>
参考资料见the section on Formatted String Literals:
[..] While other string literals always have a constant value, formatted strings are really expressions evaluated at run time. [..]
执行表达式(查找替换字段及其后续格式化)后,它们没有什么特别之处,表达式已被评估为字符串并分配给 baz
。
字符串是不可变的,字符串一旦创建,就不能再更改。
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
的原始分配并在内存中创建了一个新分配。