string.templatelib — 对模板字符串字面量的支持

源代码: Lib/string/templatelib.py


模板字符串

在 3.14 版本加入。

模板字符串是一种自定义字符串处理机制。它们具有 Python f-strings 的全部灵活性,但在它们组合**之前**返回一个 Template 实例,该实例允许访问字符串的静态部分和内插(在花括号中)部分。

要编写 t-string,请使用 't' 前缀而不是 'f',如下所示:

>>> pi = 3.14
>>> t't-strings are new in Python {pi!s}!'
Template(
   strings=('t-strings are new in Python ', '!'),
   interpolations=(Interpolation(3.14, 'pi', 's', ''),)
)

类型

class string.templatelib.Template

Template 类描述模板字符串的内容。它是不可变的,这意味着模板的属性不能被重新赋值。

创建 Template 实例最常见的方式是使用模板字符串字面量语法。此语法与 f-strings 的语法相同,只是它使用 t 前缀代替 f

>>> cheese = 'Red Leicester'
>>> template = t"We're fresh out of {cheese}, sir."
>>> type(template)
<class 'string.templatelib.Template'>

模板以字面量 strings 和动态 interpolations 序列的形式存储。values 属性包含内插的值。

>>> cheese = 'Camembert'
>>> template = t'Ah! We do have {cheese}.'
>>> template.strings
('Ah! We do have ', '.')
>>> template.interpolations
(Interpolation('Camembert', ...),)
>>> template.values
('Camembert',)

strings 元组比 interpolationsvalues 多一个元素;内插“属于”字符串之间。当元组对齐时,这可能更容易理解。

template.strings:  ('Ah! We do have ',              '.')
template.values:   (                   'Camembert',    )

属性

strings: tuple[str, ...]

模板中静态字符串的 tuple

>>> cheese = 'Camembert'
>>> template = t'Ah! We do have {cheese}.'
>>> template.strings
('Ah! We do have ', '.')

空字符串**包含**在元组中。

>>> response = 'We do have '
>>> cheese = 'Camembert'
>>> template = t'Ah! {response}{cheese}.'
>>> template.strings
('Ah! ', '', '.')

strings 元组永远不为空,并且总是比 interpolationsvalues 元组多一个字符串。

>>> t''.strings
('',)
>>> t''.values
()
>>> t'{'cheese'}'.strings
('', '')
>>> t'{'cheese'}'.values
('cheese',)
interpolations: tuple[Interpolation, ...]

模板中内插的 tuple

>>> cheese = 'Camembert'
>>> template = t'Ah! We do have {cheese}.'
>>> template.interpolations
(Interpolation('Camembert', 'cheese', None, ''),)

interpolations 元组可能为空,并且总是比 strings 元组少一个值。

>>> t'Red Leicester'.interpolations
()
values: tuple[object, ...]

模板中所有内插值的元组。

>>> cheese = 'Camembert'
>>> template = t'Ah! We do have {cheese}.'
>>> template.values
('Camembert',)

values 元组的长度总是与 interpolations 元组相同。它总是等同于 tuple(i.value for i in template.interpolations)

方法

__new__(*args: str | Interpolation)

虽然字面量语法是创建 Template 最常见的方式,但也可以使用构造函数直接创建它们。

>>> from string.templatelib import Interpolation, Template
>>> cheese = 'Camembert'
>>> template = Template(
...     'Ah! We do have ', Interpolation(cheese, 'cheese'), '.'
... )
>>> list(template)
['Ah! We do have ', Interpolation('Camembert', 'cheese', None, ''), '.']

如果连续传递多个字符串,它们将被连接成 strings 属性中的单个值。例如,以下代码创建一个 Template,其中包含一个最终字符串。

>>> from string.templatelib import Template
>>> template = Template('Ah! We do have ', 'Camembert', '.')
>>> template.strings
('Ah! We do have Camembert.',)

如果连续传递多个内插,它们将被视为单独的内插,并在它们之间插入一个空字符串。例如,以下代码创建一个模板,其中 strings 属性中包含空占位符。

>>> from string.templatelib import Interpolation, Template
>>> template = Template(
...     Interpolation('Camembert', 'cheese'),
...     Interpolation('.', 'punctuation'),
... )
>>> template.strings
('', '', '')
iter(template)

遍历模板,按正确顺序生成每个非空字符串和 Interpolation

>>> cheese = 'Camembert'
>>> list(t'Ah! We do have {cheese}.')
['Ah! We do have ', Interpolation('Camembert', 'cheese', None, ''), '.']

注意

空字符串**不**包含在迭代中。

>>> response = 'We do have '
>>> cheese = 'Camembert'
>>> list(t'Ah! {response}{cheese}.')
['Ah! ',
 Interpolation('We do have ', 'response', None, ''),
 Interpolation('Camembert', 'cheese', None, ''),
 '.']
template + other
template += other

将此模板与另一个模板连接,返回一个新的 Template 实例。

>>> cheese = 'Camembert'
>>> list(t'Ah! ' + t'We do have {cheese}.')
['Ah! We do have ', Interpolation('Camembert', 'cheese', None, ''), '.']

不支持连接 Templatestr。这是因为不清楚字符串应被视为静态字符串还是内插。如果您想将 Template 与字符串连接,您应该直接将字符串包装在 Template 中(将其视为静态字符串)或使用 Interpolation(将其视为动态)。

>>> from string.templatelib import Interpolation, Template
>>> template = t'Ah! '
>>> # Treat 'We do have ' as a static string
>>> template += Template('We do have ')
>>> # Treat cheese as an interpolation
>>> cheese = 'Camembert'
>>> template += Template(Interpolation(cheese, 'cheese'))
>>> list(template)
['Ah! We do have ', Interpolation('Camembert', 'cheese', None, '')]
class string.templatelib.Interpolation

Interpolation 类型表示模板字符串中的表达式。它是不可变的,这意味着内插的属性不能被重新赋值。

内插支持模式匹配,允许您使用 match 语句 匹配其属性。

>>> from string.templatelib import Interpolation
>>> interpolation = t'{1. + 2.:.2f}'.interpolations[0]
>>> interpolation
Interpolation(3.0, '1. + 2.', None, '.2f')
>>> match interpolation:
...     case Interpolation(value, expression, conversion, format_spec):
...         print(value, expression, conversion, format_spec, sep=' | ')
...
3.0 | 1. + 2. | None | .2f

属性

value: object

内插的求值结果。

>>> t'{1 + 2}'.interpolations[0].value
3
expression: str

对于由 t-string 字面量创建的内插,expression 是花括号({})内的表达式文本,包括任何空白,但不包括花括号本身,并且在第一个 !:= 之前结束(如果存在)。对于手动创建的内插,expression 是在构造内插实例时提供的任意字符串。

我们建议为手动创建的 Interpolation 实例的 expression 字段使用有效的 Python 表达式或空字符串,尽管这在运行时并未强制执行。

>>> t'{1 + 2}'.interpolations[0].expression
'1 + 2'
conversion: Literal['a', 'r', 's'] | None

要应用于值或 None 的转换。

conversion 是要应用于值的可选转换。

>>> t'{1 + 2!a}'.interpolations[0].conversion
'a'

备注

与 f-strings 不同,f-strings 会自动应用转换,t-strings 的预期行为是**处理** Template 的代码将决定如何解释和是否应用 conversion。为了方便起见,convert() 函数可用于模仿 f-string 转换语义。

format_spec: str

要应用于值的格式规范。

format_spec 是一个可选的任意字符串,用作呈现值的格式规范。

>>> t'{1 + 2:.2f}'.interpolations[0].format_spec
'.2f'

备注

与 f-strings 不同,f-strings 会通过 format() 协议自动应用格式规范,t-strings 的预期行为是**处理**内插的代码将决定如何解释和是否应用格式规范。因此,内插中的 format_spec 值可以是任意字符串,包括不符合 format() 协议的字符串。

方法

__new__(value: object, expression: str, conversion: Literal['a', 'r', 's'] | None = None, format_spec: str = '')

从组成部分创建一个新的 Interpolation 对象。

参数:
  • value – 内插的已求值、在作用域内的结果。

  • expression – 有效 Python 表达式的文本,或空字符串。

  • conversion – 要使用的 转换,可以是 None'a''r''s'

  • format_spec – 一个可选的任意字符串,用作呈现值的 格式规范

辅助函数

string.templatelib.convert(obj, /, conversion)

将格式化字符串字面量 转换 语义应用于给定对象 *obj*。这对于自定义模板字符串处理逻辑通常很有用。

目前支持三个转换标志:

  • 's' 调用 str() 对值进行操作(类似于 !s),

  • 'r' 调用 repr()(类似于 !r),以及

  • 'a' 调用 ascii()(类似于 !a)。

如果转换标志为 None,则返回 *obj* 未更改。