我感觉几乎每次在 Python 中读取文件时,我想要的是:
with open("filename") as file_handle:
for line in file_handle:
#do something
这真的是首选成语吗?这让我有点恼火,这双缩进所有文件读取逻辑。有没有办法将此逻辑折叠成一行或一层?
For simple cases, yes, the two-level with
and for
is idiomatic.
For cases where the indentation becomes a problem, here as anywhere else in Python, the idiomatic solution is to find something to factor out into a function.
You can write wrappers to help this. For example, here's a simple way to solve some of the problems you use with
for (e.g., even in the best case, the file sticks around after you finish the loop, until the end of the scope—which could be days later, or never, if the scope is a main event loop or a generator or something…):
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
Of course it doesn't solve everything. (See this ActiveState recipe for more details.)
If you know that it does what you want, great. If you don't understand the differences… stick to what's idiomatic; it's idiomatic for a reason.
So, how do you refactor the code? The simplest way is often to turn the loop body into a function, so you can just use map
or a comprehension:
def do_with_line(line):
return line
with open("filename") as f:
process = [do_with_line(line) for line in f]
But if the problem is that the code above or underneath the for
is too deep, you'll have to refactor at a different level.
是的,这绝对是惯用的 Python。
你不应该被多层次的缩进所困扰。当然,这不是它发生的唯一方式,例如
if condition:
for x in sequence:
#do something with x
如果缩进级别变得太大,是时候重构为多个函数了。我最喜欢 Python 的一件事是它减少了分解事物的摩擦。
with open("filename") as file_handle:
result = do_something(file_handle)
简而言之,不,如果你想保持完全相同的语义。
如果单个缩进会减少对您的刺激,您总是可以这样做:
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
还是要小心大文件!因为这一切都是在记忆中完成的。
明确地说:
@我自己,当然是成语了!成语中的 with/for 行提供了几个好处: