在Python中生成tokenizer函数的高效且干净的方法

时间:2011-10-06 19:45:10

标签: python performance tokenize

我有一个可以进行“翻译”的库,并使用了很棒的tokenize.generate_tokens()函数来实现这一目的。

它非常快,我的工作正常。但是在翻译时,我发现函数会随着我想翻译的新标记不断增长而ifelif条件开始全面弹出。我还在生成器之外保留了一些变量,用于跟踪“看到的最后一个关键字”和类似内容。

这方面的一个很好的例子是这里看到的实际Python文档(在底部):http://docs.python.org/library/tokenize.html#tokenize.untokenize

每当我添加一个新东西时,我需要翻译这个函数会增加几个条件。我不认为拥有这么多条件的功能是通过什么方式或正确的方式来铺平地。

此外,我觉得令牌化器消耗了许多不相关的行,这些行不包含我正在翻译的任何关键字。

所以有2个问题:

  1. 如何避免添加越来越多的条件语句,使这个翻译功能变得容易/干净以保持增长(没有性能损失)?

  2. 如何才能使我对我不感兴趣的所有不相关行有效?

1 个答案:

答案 0 :(得分:3)

您可以使用dict调度程序。例如,您链接的代码可能如下所示:

def process_number(result,tokval):
    if '.' in tokval:
        result.extend([
            (NAME, 'Decimal'),
            (OP, '('),
            (STRING, repr(tokval)),
            (OP, ')')
            ])
def process_default(result,tokval):
    result.append((toknum, tokval))

dispatcher={NUMBER: process_number, }
for toknum, tokval, _, _, _  in g:
    dispatcher.get(toknum,process_default)(result,tokval)

您可以将键值对添加到if,而不是添加更多dispatcher - 块。

这可能比评估if-else条件的长列表更有效,因为dict查找是O(1),但它确实需要函数调用。您需要进行基准测试,以了解这与许多if-else块进行比较。

我认为它的主要优点是它可以将代码组织成小型(易),易于理解的单元。