我正在尝试处理文件列表,其中每个文件可能是常规文本文件或bz2存档。
如何最有效地使用try-except块来尝试以适当的格式打开每个文件?我宁愿不检查文件的扩展名,因为这不能总是依赖(并且不是EAFP)。
目前我在做:
def data_generator(*corpora):
def parse_lines(fobj):
for line in fobj:
# Do lots of processing.
# ...
# Many lines here omitted.
yield ('lots', 'of', 'data')
for corpus in corpora:
try:
with bz2.BZ2File(corpus, mode='r') as f:
for data in parse_lines(f):
yield data
except IOError:
with codecs.open(corpus, encoding='utf-8') as f:
for data in parse_lines(f):
yield data
我认为重复的for data in parse_lines(f): ...
代码看起来多余,但我想不出办法摆脱它。有没有办法减少之前的,还是有另一种方法来尝试“智能打开”文件?
扩大检查格式数量的适当方法是什么?例如,程序7zip允许您右键单击任何文件并尝试将其作为存档(任何7zip支持)打开。使用当前的try-except块策略,看起来即使在几种格式之后你也会很快嵌套在块中,例如:
try:
f = ...
except IOError:
try:
f = ...
except IOError:
try:
...
答案 0 :(得分:1)
如果它真的只是你所关心的重复循环,你可以将f
移出try-catch块的范围,然后在完成所有内容之后放置一个循环的副本:< / p>
try:
f = bz2.BZ2File(corpus, mode='r')
except IOError:
f = codecs.open(corpus, encoding='utf-8')
for data in parse_lines(f):
yield data
f.close()
虽然我只考虑打开文件一次,检查BZ2标头(字符BZ
作为前两个字节),并用它来决定是继续以明文形式读取,还是通过将数据转换为bz2.BZ2Decompressor
实例。