Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用python设计可重用的解析器_Python - Fatal编程技术网

用python设计可重用的解析器

用python设计可重用的解析器,python,Python,我正在编写一个文件解析器,我希望能够确定它将返回给我的“数据字段” 我开始学习python,仍然习惯于像Java程序员一样思考,所以这个问题更多的是关于如何设计我的模块,而不是如何具体解析文件 根据上下文,文件的每一行都有固定数量的字符,并且每个信息都包含在特定索引之间。例如: XX20120101NAME1CITYA XY20120101NAME2CITYB 在这个虚构的例子中,从索引0到索引2,您有一个信息,从索引2到索引10,依此类推 使用Java,我通常会创建一个表示不同信息片段的枚举

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

我开始学习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可以不那么冗长,但我不知道有什么好的设计实践可以达到同样的结果

值得一提的是,我不想让模块的用户暴露在不必要的复杂性之下,也不想强迫他知道每个信息的索引。模块的用户最好能够确定他想要的信息及其顺序

那么,你对优雅地解决这些必要条件有什么见解吗?
提前感谢

Python已经有了一个内置类型,它完成了FileInformation所做的事情—请检查

以下是您的模块的外观:

# 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
有getter,但没有setter-
namedtuple
s同样是不可变的):


这非常有帮助。很多有用的信息。。。感谢INFO01,INFO02,INFO03,INFO04=map(slice,((0,2),(2,10),(10,15),(15,20)))我不得不用INFO01,INFO02,INFO03,INFO04=[slice(I[0],I[1]代替我在[(0,2),(2,10),(10,15),(15,20)]啊!那么这也应该起作用:
INFO01,INFO02,INFO03,INFO04,INFO04=[slice(*I)代替[(0,2),(2,10),(10,15),(15,20)]
“*”告诉Python将每个元组
i
解压为
slice
的参数。对于命名的元组,可能也需要同样的技巧。
from collections import namedtuple
FileInformation = namedtuple("FileInformation", "start end")
INFO01, INFO02, INFO03, INFO04 = map(FileInformation, ((0,2),(2,10),(10,15),(15,20)))