在python中设计可重用的解析器

时间:2012-08-11 03:42:22

标签: python

我正在编写一个文件解析器,我希望能够确定它将为我返回的“数据字段”。

我开始学习python,我仍然习惯像Java程序员一样思考,所以这个问题更多的是关于如何设计我的模块而不是如何专门解析文件。

上下文化,文件的每一行都有固定数量的字符,每个信息都包含在特定索引之间。例如:

XX20120101NAME1CITYA
XY20120101NAME2CITYB

在这个虚构的例子中,从索引0到2你有一个信息,从2到10另一个,依此类推......

使用Java,我通常会创建一个表示不同信息的枚举器,每个信息“存储”开始索引结束索引。在我的解析类中,我将创建一个方法可用设计来接受 n 不同的枚举。例如:

enum FileInformation {
    INFO01(0,2), INFO02(2,10), INFO03(10,15), INFO04(15,20);
    int startIndex;
    int endIndex;

    public FileInformation(int si, int ei)  {
        this.startIndex = si;
        this.endIndex = ei;
    }

    public int getStartIndex() { return si; }
    public int getEndIndex() { return ei; }
}

public Whatever parse(FileInformation... infos) {
    // Here I would iterate through infos[], 
    // using its start and end index to retrieve only what I need.
}

我知道我可能不应该在 python 中使用相同的行,特别是因为语言不允许它(python中没有枚举),因为我想 python < / em>可能不那么冗长,但我不知道一个好的设计实践来实现同样的结果。

有必要提一下,我不想让模块的用户暴露于不必要的复杂性,或者强迫他知道每个信息的索引。模块的用户应该最好能够确定他想要的女巫信息及其顺序。

那么,您是否有任何关于以优雅的方式解决这些要求的见解? 提前致谢

1 个答案:

答案 0 :(得分:2)

Python已经有一个内置类型,可以执行FileInformation的操作 - 查看slice

以下是您的模块的外观:

# module dataparser.py

INFO01, INFO02, INFO03, INFO04 = map(slice, ((0,2),(2,10),(10,15),(15,20)))

def parse(infos, data):
    return [data[info] for info in infos]

调用模块如何使用它:

# module dataparser_user.py

import dataparser as dp

data = """\
XX20120101NAME1CITYA
XY20120101NAME2CITYB""".splitlines()

for d in data:
    print d, dp.parse((dp.INFO01, dp.INFO03), d)

# or use partial to define a function object that takes your 
# subset number of slices
from functools import partial
specific_parse = partial(dp.parse, (dp.INFO01, dp.INFO03))

for d in data:
    print d, specific_parse(d)

如果您要在Python中实现自己的enum模拟,我认为namedtuple将是最接近的东西(因为您的Java enum有吸气剂但没有设置者 - {{1同样是不可变的):

namedtuple