Python脚本中使用Vim编辑器的临时文件

5

我成功找到了一段代码,可以从Python脚本中生成一个临时文件并启动vim编辑器。这段代码在这里,我在这里找到它:call up an EDITOR (vim) from a python script

import sys, tempfile, os
from subprocess import call

EDITOR = os.environ.get('EDITOR','vim') 

initial_message = "" 

with tempfile.NamedTemporaryFile(suffix=".tmp") as tempfile:
  tempfile.write(initial_message)
  tempfile.flush()
  call([EDITOR, tempfile.name])

我遇到的问题是,编辑器退出后我无法访问临时文件的内容。
tempfile
<closed file '<fdopen>', mode 'w+b' at 0x87c47b0>

tempfile.readline()

I get

ValueError: I/O operation on closed file

我做了:

myfile = open(tempfile.name)
IOError: [Errno 2] No such file or directory: '/tmp/tmp7VKzfl.tmp'

编辑器修改文件后,我该如何在Python脚本中访问该文件?

谢谢。

3个回答

5

with代码块内的所有内容都是受作用域限制的。如果你使用with语句创建临时文件,则在该代码块结束后,该文件将不再可用。

你需要在with代码块内读取临时文件的内容,或者使用其他语法来创建临时文件,例如:

tempfile = NamedTemporaryFile(suffix=".tmp")
# do stuff
tempfile.close()

如果您想在程序块结束后自动关闭文件,但仍然可以重新打开它,请在NamedTemporaryFile构造函数中传递delete=False(否则将在关闭后删除):

with tempfile.NamedTemporaryFile(suffix=".tmp", delete=False) as tempfile:

顺便说一下,你可能希望使用envoy来运行子进程,这是一个很好的库 :)


3
我遇到了同样的问题并且有同样的疑问。
仅仅为了读取它而不删除一个临时文件似乎不是最佳实践。我找到了以下方法来读取命名临时文件的实例中编辑过的内容,并保留删除临时文件的优势。(如果它不能自动删除,那么它就不是临时的,对吗?)
必须倒回临时文件然后再读取它。我在这里找到了答案:http://pymotw.com/2/tempfile/
import os
import tempfile
from subprocess import call

temp = tempfile.TemporaryFile()
try:
    temp.write('Some data')
    temp.seek(0)

    print temp.read()
finally:
    temp.close()

这是我在脚本中使用的实际代码:

import tempfile
import os
from subprocess import call

EDITOR = os.environ.get('EDITOR', 'vim')
initial_message = "Please edit the file:"

with tempfile.NamedTemporaryFile(suffix=".tmp") as tmp:
    tmp.write(initial_message)
    tmp.flush()
    call([EDITOR, tmp.name])
    #file editing in vim happens here
    #file saved, vim closes
    #do the parsing with `tempfile` using regular File operations
    tmp.seek(0)
    print tmp.read()

2
< p > NamedTemporaryFile 创建一个在关闭后被删除的文件(文档)。因此,当您需要将某些内容写入临时文件并在关闭文件后读取其内容时,不适合使用该函数。

请改用mkstemp (文档):

f, fname = mkstemp(suffix=".tmp")
f.write("...")
f.close()
call([EDITOR, fname])

我不知道delete=False(请参见被接受的答案)。无论如何,我会保留我的答案,因为它展示了解决问题的另一种有效方法。 - codeape

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