Python 使用动态长度字符串(使用 *)和关键字参数(不是 `string.format`)的字符串插值

Python string interpolation using dynamic length strings (using *) with keyword arguments (not `string.format`)

对于在很多地方使用字符串插值系统的遗留系统,我需要实现一些代码来格式化具有特定长度的字符串。我知道 rjustljust 可以解决这个问题,但我正在尝试回答标准字符串插值系统是否可行的问题。

示例:

>>> '%0*d' % (5, 3)
'00003'
>>> '%(value)05d' % dict(value=3)
'00003'

现在的问题是,如何将这两者结合起来?

我失败的尝试:

>>> '%(value)*d' % dict(value=(5, 3))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: * wants int
>>> '%(value)*d' % dict(value=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
>>> '%(value)*d' % {'*': 5, 'value': 3}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
>>> '%(value)*d' % {'*value': 5, 'value': 3}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string

问题是:如何使用字符串插值来组合星号和关键字参数?


注意: str.format 不是这个问题的答案,我不是在寻找替代方案,而只是为了回答这是否可能的问题。用 str.format 替换字符串插值将需要当前库的许多用户修改函数调用,这在不久的将来是一个不利的选择。

不,你不能这样做。每 the documentation(强调我的):

  1. Minimum field width (optional). If specified as an '*' (asterisk), the actual width is read from the next element of the tuple in values, and the object to convert comes after the minimum field width and optional precision.

您需要传递一个元组,而不是字典,作为使用 * 字段宽度的值。然后将其明确化:

When the right argument is a dictionary (or other mapping type), ... no * specifiers may occur in a format (since they require a sequential parameter list).