首选文件逐行读取Python中的习语

时间:2013-08-20 19:30:39

标签: python file-io idioms

我几乎每次用Python读取文件时,我想要的是:

with open("filename") as file_handle:
    for line in file_handle:
        #do something

这真的是首选的成语吗?这种双重缩进所有文件读取逻辑,这有点让我感到恼火。有没有办法将这个逻辑折叠成一行或一层?

5 个答案:

答案 0 :(得分:3)

对于简单的情况,是的,两级withfor是惯用的。

对于缩进成为问题的情况,这里与Python中的任何其他地方一样,惯用的解决方案是找到一些东西分解成函数。


您可以编写包装来帮助它。例如,这是解决您使用with的一些问题的简单方法(例如,即使在最好的情况下,文件在完成循环后仍然存在,直到范围结束 - 这可能是几天后,或者永远不会,如果范围是主事件循环或生成器或某事......):

def with_iter(iterable):
    with iterable:
        yield from iterable

for line in with_iter(open("filename")):
    # do something

for line in with_iter(open("other_filename")):
    # do something else

当然它并不能解决所有问题。 (有关详细信息,请参阅this ActiveState recipe。)

如果你知道它能做到你想要的,那很好。如果你不理解差异......坚持什么是惯用的;出于某种原因,这是惯用的。


那么,你如何重构代码呢?最简单的方法通常是将循环体转换为函数,因此您可以使用map或理解:

def do_with_line(line):
    return line

with open("filename") as f:
    process = [do_with_line(line) for line in f]

但如果问题是for上方或下方的代码太深,则必须在不同的级别进行重构。

答案 1 :(得分:2)

是的,这绝对是惯用的Python。

你不应该被多级缩进困扰太多。当然,这不是发生这种情况的唯一方法,例如。

if condition:
    for x in sequence:
        #do something with x

如果缩进程度变得太大,则需要重构为多个函数。我最喜欢Python的一个方面是它减少了破坏的摩擦。

with open("filename") as file_handle:
    result = do_something(file_handle)

答案 2 :(得分:1)

简而言之,不,如果你想保持完全相同的语义。

答案 3 :(得分:0)

如果单次缩进会刺激你,那么你可以随时做:

with open("filename") as file_handle:
    fle = file_handle.read()

但是要小心处理大文件,因为在整个文件淤变后它会进入你机器的内存。你可以实现单个缩进,并且如果你这样做,仍然可以逐行迭代:

with open("filename") as file_handle:
    fle = file_handle.readlines()

您文件中的行将放在列表中,每个行都在单独的元素中,然后您可以像这样迭代它:

for ln in fle:
    #do something with ln here, it contain one line from your file

还要小心大文件!因为这一切都是在记忆中完成的。

答案 4 :(得分:0)

只是要明确:

@我自己,当然这就是成语!成语中的with / for行提供了几个好处:

  • 它会自动关闭错误文件。
  • 它按块查入文件块,限制内存使用。
  • 广泛使用;其他程序员会立即理解它。