关于迭代:如何在使用for循环内部时格式化Python

How to format Python when using for loop inside with block

我最近才开始使用with来打开文件,而不是更老的学校单独的打开/关闭调用。

但是,我发现这意味着我所有要迭代文件的代码现在都有两个缩进:

1
2
3
with open('filename', 'rb') as f:
    for line in f:
        # do stuff

这有点难看,相比之下:

1
2
3
4
f = open('filename', 'rb')
for line in f:
    # do stuff
f.close()

我试过了:

1
2
3
with open('filename', 'rb') as f:
  for line in f:
    # do stuff

所以"东西"只有一个缩进,但这让各种各样的绒线格抱怨。有更好的方法来处理这个吗?

注意:我很欣赏上下文管理器的额外好处,我只是在寻找格式化代码的最佳方法。


您不必将逻辑放在with块中:

1
2
3
4
5
with open('filename', 'rb') as f:
    file_content = f.readlines()

for line in file_content:
    # do stuff

这种方法的缺点是需要将整个文件保存到file_content列表中。

如果将读取逻辑隐藏在一个单独的函数中,您仍然可以从生成器中获益:

1
2
3
4
5
6
7
8
def read_file(file_path):
    with open(file_path, 'rb') as f:
        for line in f:
            yield line
        # or simply `yield from f` in Python 3

for line in read_file(file_path):
    # do stuff

但所有这些对于像两级缩进这样微不足道的东西来说,可能都是完全多余的。你最好学着接受它。


对我来说,你的原始代码是完美的:

1
2
3
with open('filename', 'rb') as f:
    for line in f:
        # do stuff

但是,如果#do stuff变得太大,我建议您使用一个函数:

1
2
3
4
5
6
def do_stuff(f):
    for line in f:
        # do stuff

with open('filename', 'rb') as f:
    do_stuff(f)

当性能不是问题时,将文件内容存储在变量中是很常见的:

1
2
3
4
5
with open('filename', 'rb') as f:
    lines = f.readlines()

for line in lines:
    # do stuff

当您需要同时操作多个文件,并且不希望嵌套多个with结构时,这更有用。


@马克西姆的评论胜过一切:

1
2
3
4
5
6
def read_file(file_path):
    with open(file_path, 'rb') as f:
        yield from f

for line in read_file('filename'):
    # do sth

这使用了python的yield from,在实践中解释了,python 3.3中新的"yield-from"语法的主要用途是什么?.

为了验证您的担忧,这里是python的禅(import this)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you'
re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let'
s do more of those!

四点钟真的很难看(?)以及更多级别的缩进。在这种情况下,建议您清除此问题,并将整个文件处理代码移动到一个函数中,如:

1
2
3
4
5
6
with open('filename', 'rb') as f:
    parse_file(f)

def parse_file(f):
    for line in f:
        # do stuff

当你开始在组合中添加类等时,它会变得很深……

除此之外:你有没有一个好的编辑,可以简化缩进等?虽然不是对每个人都适用,但Emacs实际上对python非常适用。