在Python中使用with open()打开文件后,如何使已打开的文件无法被seek(0)倒回。

3

当我尝试在Python中逐行打印文件内容时,如果使用 with open("file_name") as f: 打开文件,则无法通过 f.seek(0) 倒回文件并打印内容。

但是,如果使用 open("file_name") as f: 则可以实现。

以下是我的代码:

with open("130.txt", "r") as f:             #f is a FILE object
    print (f.read())                        #so f has method: read(), and f.read() will contain the newline each time 

f.seek(0)                             #This will Error!
with open("130.txt", "r") as f:       #Have to open it again, and I'm aware the indentation should change  
for line in f:                    
    print (line, end="")          

f = open("130.txt", "r")
f.seek(0)
for line in f:
    print(line, end="")

f.seek(0)                           #This time OK!
for line in f:
    print(line, end="")

我是一个Python初学者,有谁可以告诉我为什么?

2个回答

7
第一个f.seek(0)会报错,因为
with open("130.txt", "r") as f:
    print (f.read())

在代码块结束时,将关闭文件(一旦文件被打印出来)。

你需要做类似这样的操作:

with open("130.txt", "r") as f:
    print (f.read())

    # in with block
    f.seek(0)

2
< p > with 的目的是在块结束时清理资源,在本例中包括关闭文件句柄。

您应该能够像这样在 with 块内使用 .seek

with open('130.txt','r') as f:
  print (f.read())

  f.seek(0)
  for line in f:
    print (line,end='')

从您的评论中可以看出,在这种情况下,with 是一种类似于以下代码的语法糖:

f = open(...)
try:
  # use f
finally:
  f.close()

# f is still in scope, but the file handle it references has been closed

谢谢!第一个文件对象f会消失吗? 使用*type(f)*我得到了:<class '_io.TextIOWrapper'>,看起来它仍然存在。对我来说,切换到Python有点困难。 - Yifangt
f仍然存在并引用文件句柄的包装器,但它实际上包装的句柄已经关闭,因此当进行后续调用时将会失败。我当然希望f的作用域限定在with块内,但是Python对这种事情相当宽松。 - ryachza
我明白了,处理程序还在那里,但它包裹的内容已经关闭了。问题解决了!非常感谢! - Yifangt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接