我几乎每次用Python读取文件时,我想要的是:
with open("filename") as file_handle:
for line in file_handle:
#do something
这真的是首选的成语吗?这种双重缩进所有文件读取逻辑,这有点让我感到恼火。有没有办法将这个逻辑折叠成一行或一层?
答案 0 :(得分:3)
对于简单的情况,是的,两级with
和for
是惯用的。
对于缩进成为问题的情况,这里与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行提供了几个好处: