如何从Python(传统)格式字符串中提取字段名称?

问题描述:

我觉得这是一个难以置于单词中的问题,因此是例子。然而,我基本上被给予arbitrary format strings,我需要(有效地)从数据库中获取适当的值,以便动态地构建相关的映射对象。如何从Python(传统)格式字符串中提取字段名称?

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

>>> '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_name S,A每个列表的文档)。

+1

请注意,您的方法可行,但只针对'{}'样式的格式:''你好,{第一name}等!你是#{customer-number} d.'' – beerbajay 2012-02-25 20:30:23

+0

@beerbajay:测试过^,你说得对...我想现在改变风格还不算太迟。为什么它适用于一种风格而不适用于另一种风格?有关于此的任何文档? – Dolph 2012-02-25 20:34:53

+0

由于'string.Formatter'稍后实施(在[PEP-3101](http://www.python.org/dev/peps/pep-3101/)之后)。 – beerbajay 2012-02-25 20:41:03

当使用%运算符来格式化字符串时,右操作数不一定是字典 - 它只需要一些对象将必需的字段名映射到应该被置换的值。所以你所要做的就是编写一个重新定义的类__getitem__(),它从数据库中检索这些值。

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

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

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

打印

Hello, first-name! 
+0

我需要在单个查询中检索所有值,但这非常酷,而且我可以使用它:) – Dolph 2012-02-25 20:37:21

+0

您可以使用这种方式获取所有值,只需编写您的'Mapper',以便保存每个'项目'到内部缓存并在运行格式化操作后读出所有值。例如而不是'return item',在内部'items'列表上执行'self.items.append(item)'。 – beerbajay 2012-02-25 20:42:33

+0

@Dolph:你当然可以使用它来收集所需项目的名称,构建字典并在第二个%操作中执行实际的格式化。 (可能这就是你所说的“我可以使用它”的意思。) – 2012-02-25 20:43:25