【问题标题】:How can I extract the field names from a Python (legacy) format string?如何从 Python(旧版)格式字符串中提取字段名称?
【发布时间】:2012-02-25 20:19:00
【问题描述】:

我发现这是一个难以用语言表达的问题,因此提供了示例。但是,我基本上得到了arbitrary format strings,我需要(有效地)从数据库中获取适当的值,以便动态构建相关的映射对象。

给定一个期望映射对象的格式字符串,例如:

>>> 'Hello, %(first-name)s!' % {'first-name': 'Dolph'}
'Hello, Dolph!'

我正在寻找下面的“infer_field_names()”的实现:

>>> infer_field_names('Hello, %(first-name)s! You are #%(customer-number)d.')
['first-name', 'customer-number']

我知道我可以编写正则表达式(甚至尝试解析异常消息!),但我希望有一个现有的 API 调用我可以使用......?

基于string Formatter docs,我认为这可行:

>>> import string
>>> format_string = 'Hello, %(first-name)s! You are #%(customer-number)d.'
>>> [x[1] for x in string.Formatter().parse(format_string)]
[None]

但这并不完全符合我的预期(field_names 的列表,根据文档)。

【问题讨论】:

  • 请注意,您的方法有效,但仅适用于{}-style 格式:'Hello, {first-name}s! You are #{customer-number}d.'
  • @beerbajay:测试过 ^,你是对的......我想现在改变风格还为时不晚。为什么它适用于一种风格而不适用于另一种风格?有任何相关文档吗?
  • 因为string.Formatter是后来实现的(在PEP-3101之后)。

标签: python regex string string-formatting


【解决方案1】:

当使用% 运算符格式化字符串时,正确的操作数不必是字典——它只需要将所需字段名称映射到应该被替换的值的某个对象。因此,您需要做的就是编写一个重新定义 __getitem__() 的类,该类从数据库中检索值。

这是一个毫无意义的例子:

class Mapper(object):
    def __getitem__(self, item):
        return item   

print 'Hello, %(first-name)s!' % Mapper()

打印

Hello, first-name!

【讨论】:

  • 我需要在单个查询中检索所有值,但这真的很酷,我可以使用它:)
  • 您可以通过这种方式获取所有这些值,只需写入您的Mapper,以便它将每个item 保存到内部缓存并在您运行格式化操作后读出所有值。例如而不是return item,在内部items 列表上执行self.items.append(item)
  • @Dolph:您当然可以使用它来收集所需项目的名称,构建字典并在第二个 % 操作中进行实际格式化。 (可能这就是您所说的“我可以使用它”的意思。)
  • @beerbajay, Sven:这正是我所做的
猜你喜欢
  • 2016-10-15
  • 2019-08-22
  • 2014-11-17
  • 2012-06-25
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
  • 1970-01-01
  • 2013-05-02
相关资源
最近更新 更多