Python文件包装,最佳设计?

0 投票
1 回答
1979 浏览
提问于 2025-04-18 15:08

我需要解析一个特定领域的配置文件,但在开始提取有用信息之前,我想先去掉里面的注释。

去掉注释后,我仍然想使用一些功能,比如 getline()seek()tell()

(因为去掉大块内容后,寻址的偏移量是可以接受的,因为所有解析都在一个解析对象中完成)

要从 file 继承吗?:

我最初的想法是创建一个像 MyFile(file) 这样的对象,并重写 __init__ 方法来创建一个 self.content 字符串,然后重写所有与文件访问相关的功能……但这看起来太复杂了(我看到很多论坛帖子里的人尝试这个都遇到了麻烦)

委托给 file 对象?:

创建一个 MyFile(file) 类,这个类内部创建一个 file 类,并将来自 MyFile 实例的调用委托给内部的 file 实例。如果对 MyFile 的调用期望返回的内容超出了注释查找/替换的参数,这样做是有意义的……例如:getline() 对于单行注释是可以的,但如果文件的前3行是一个整体注释块,使用 getline() 两次就不太行了,这样会需要很多麻烦的代码(更不用说还要跟踪 seek() 的偏移量)

在临时文件中重新创建?:

最后,我觉得解析整个文件然后将其重新保存为临时文件的做法有点懒……然后返回一个指向那个文件的句柄(下面是演示代码)

import re
import tempfile

FILE_NAME = 'some_file.ldf'

# ideal case
fh = open(FILE_NAME)

# my example

def getHandle(self, filename, mode='r'):
    # ----- Remove comments -----
    with open(filename, mode=mode) as fh:
        content = fh.read()
    # remove /* ... */ comment blocks
    content = re.sub(re.compile(r'/\*.*?\*/', re.DOTALL | re.MULTILINE), '', content, re.DOTALL | re.MULTILINE)
    # remove // ... line comments
    content = re.sub(r'//.*', '', content)

    # ----- Write to Temporary File -----
    fh = tempfile.TemporaryFile()
    fh.write(content)
    fh.seek(0)

fh = getHandle(FILE_NAME)

更好的设计?:

有没有人有更好的设计方案?……或者对这种问题有完全不同的看法。

1 个回答

2

老实说,听起来你的DSL解析器可能有问题。简单来说,如果你设计了一个DSL,它应该能够识别注释并直接忽略它们。

把这个当作文件过滤器来写是个有趣但复杂的做法——这只是掩盖了你的DSL解析器不完整的事实。

根据你写的解析器,这个问题可能容易解决,也可能不太好解决。不过,可以看看这个pyparsing的verilog解析器示例。它简单地定义了cStyleComment,并告诉解析器完全忽略这些注释。简单明了,没有麻烦。

http://pyparsing.wikispaces.com/file/view/verilogParse.py/241112725/verilogParse.py

撰写回答