是否有pythoniconeliner可以迭代文件的行?
90%的情况下,当我读取文件时,结果是这样的:是否有pythoniconeliner可以迭代文件的行?,python,file,Python,File,90%的情况下,当我读取文件时,结果是这样的: with open('file.txt') as f: for line in f: my_function(line) 这似乎是一个非常常见的情况,所以我想了一个较短的方法,但这是安全的吗?我的意思是,文件是否正确关闭,或者您是否发现此方法存在任何其他问题 for line in open('file.txt'): my_function(line) 编辑:谢谢Eric,这似乎是最好的解决方案。希望我不会就此进
with open('file.txt') as f:
for line in f:
my_function(line)
这似乎是一个非常常见的情况,所以我想了一个较短的方法,但这是安全的吗?我的意思是,文件是否正确关闭,或者您是否发现此方法存在任何其他问题
for line in open('file.txt'):
my_function(line)
编辑:谢谢Eric,这似乎是最好的解决方案。希望我不会就此进行讨论,但当我们想在几个操作中使用line(不仅仅是作为我的函数的参数)时,您对这种方法有何看法
然后使用:
for line in line_generator('groceries.txt'):
print line
grocery_list += [line]
此函数在迭代文件时是否有缺点?如果您经常需要此函数,您可以定义:
def iterate_over_file(filename, func):
with open(filename) as f:
for line in f:
func(line)
def my_function(line):
print line,
您的pythonic one liner现在是:
iterate_over_file('file.txt', my_function)
使用上下文管理器是最好的方法,这在很大程度上阻碍了一行程序解决方案的实现。如果您天真地想创建一行,您会得到:
with open('file.txt') as f: for line in f: my_function(line) # wrong code!!
这是无效的语法
所以,如果你非常想要一个班轮你可以做
with open('file.txt') as f: [my_function(line) for line in f]
但这是一种糟糕的做法,因为创建列表理解只是为了产生副作用(您不关心my_函数的返回)
另一种方法是
with open('file.txt') as f: collections.deque((my_function(line) for line in f), maxlen=0)
因此,不会创建列表理解,您可以使用itertools配方强制使用迭代器(0大小的deque:也没有分配内存)
结论:
为了达到“pythonic/one-liner”的目标,我们牺牲了可读性
有时候,最好的方法不是一行一个句号。基于,您还可以编写一个函数,使用和
打开文件,然后返回文件,从而使其更通用。然而,这是:
def with_open(filename):
with open(filename) as f:
return f # won't work!
不起作用,因为当函数返回时,文件f
将已被with
关闭。相反,您可以将其设置为生成器函数,并生成
各行:
def with_open(filename):
with open(filename) as f:
for line in f:
yield line
或更短,使用较新版本的Python:
def with_open(filename):
with open(filename) as f:
yield from f
然后像这样使用它:
for line in with_open("test.txt"):
print line
或者这个:
nums = [int(n) for n in with_open("test.txt")]
是否安全
如果其中一行中存在编码错误,并且您在退出时未关闭并处理文件句柄,则如果您遇到大量仍保留的文件句柄,可能会导致文件系统出现严重问题。好的,显然没有代码是安全的。但在这种情况下,我更想知道的是“它是否比将与
一起使用更不安全”,或者它是否有缺点。或者你的意思是将与一起使用可以解决你提到的问题吗?有趣的是,我编辑了这个问题来询问你在同一时间发布的相同方法:)我不知道更新的版本,谢谢。
nums = [int(n) for n in with_open("test.txt")]