Python 字符串变量插值:format 与 format_map 详解
本文详解 Python 中在字符串内嵌变量的多种方案。重点介绍 format() 和 format_map() 方法的使用,以及如何通过自定义 __missing__ 方法处理缺失变量以避免 KeyError。此外,还探讨了利用 sys._getframe 获取局部变量实现便捷字符串替换的高级技巧,并对比了传统 % 格式化和 string.Template 的局限性。
Python 字符串变量插值:format 与 format_map 详解
问题
你需要构建一个包含变量的字符串,其中变量名被其实际值所替代。
解决方案
使用 format 和 vars 进行变量替换
Python 并未直接提供在字符串中简单替换变量值的支持,但可以通过调用字符串的 方法来实现。例如:
>>> s = '{name} has {n} messages.'
>>> s.format(name='Guido', n=37)
'Guido has 37 messages.'
>>>
或者,若待替换的变量存在于当前作用域的变量表中,可以结合使用 format_map() 和 vars() 。具体用法如下:
>>> name = 'Guido'
>>> n = 37
>>> s.format_map(vars())
'Guido has 37 messages.'
>>>
vars() 方法同样适用于对象实例。例如:
>>> class Info:
... def __init__(self, name, n):
... self.name = name
... self.n = n
...
>>> a = Info('Guido',37)
>>> s.format_map(vars(a))
'Guido has 37 messages.'
>>>
处理缺失变量的安全替换方案
format 和 format_map() 的一个不足之处在于它们对缺失变量的处理不够友好,例如:
>>> s.format(name='Guido')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'n'
>>>
为避免此类错误,可以定义一个包含 __missing__() 方法的字典子类,如下所示:
class safesub(dict):
"""防止key找不到"""
def __missing__(self, key):
return '{' + key + '}'
随后,你可以将该类实例包装后传递给 format_map() 使用:
>>> del n # Make sure n is undefined
>>> s.format_map(safesub(vars()))
'Guido has {n} messages.'
>>>
封装工具函数简化调用
如果在代码中频繁执行此类操作,建议将变量替换逻辑封装为一个工具函数,例如:
import sys
def sub(text):
return text.format_map(safesub(sys._getframe(1).f_locals))
现在你可以按照以下方式调用该函数:
>>> name = 'Guido'
>>> n = 37
>>> print(sub('Hello {name}'))
Hello Guido
>>> print(sub('You have {n} messages.'))
You have 37 messages.
>>> print(sub('Your favorite color is {color}'))
Your favorite color is {color}
>>>
其他格式化方案对比与高级技巧
讨论
长期以来,由于 Python 缺乏内置的变量替换支持,出现了多种解决方案。如本节所示,你可能会看到类似以下的字符串格式化代码:
>>> name = 'Guido'
>>> n = 37
>>> '%(name) has %(n) messages.' % vars()
'Guido has 37 messages.'
>>>
此外,还可能见到字符串模板的使用方式:
>>> import string
>>> s = string.Template('$name has $n messages.')
>>> s.substitute(vars())
'Guido has 37 messages.'
>>>
然而,format() 和 format_map() 相比上述方案更为先进,应作为首选。使用 format() 方法的优势在于,你可以获得完整的字符串格式化支持(包括对齐、填充、数字格式化等),而这些特性是模板字符串方案无法提供的。
本节还简要介绍了一些高级特性。映射或字典类中鲜为人知的 __missing__() 方法允许你定义如何处理缺失的值。在 SafeSub 类中,该方法被定义为对缺失值返回一个占位符。这样,缺失的值会直接出现在结果字符串中(这在调试时非常有用),而不是引发 KeyError 异常。
sub() 函数利用 sys._getframe(1) 返回调用者的栈帧。通过访问 f_locals 属性,可以获取局部变量。毫无疑问,在常规代码中直接操作栈帧通常不被推荐。但对于字符串替换工具函数而言,这种方法非常实用。另外值得注意的是,f_locals 是调用函数本地变量的字典副本。尽管你可以修改 f_locals 的内容,但这些修改不会影响后续对原始局部变量的访问。因此,虽然访问栈帧看似“危险”,但对其的任何操作都不会覆盖或改变调用者的本地变量值。
以上就是 Python 字符串变量插值的详细内容,更多关于 Python 字符串中插入变量的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









