Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python子进程中使用Vim编辑临时文件在Mac OS上无法正常工作_Python_Macos_Vim_Debian_Temporary Files - Fatal编程技术网

在Python子进程中使用Vim编辑临时文件在Mac OS上无法正常工作

在Python子进程中使用Vim编辑临时文件在Mac OS上无法正常工作,python,macos,vim,debian,temporary-files,Python,Macos,Vim,Debian,Temporary Files,我最初的目标是通过命令行文本编辑器从Python脚本中获取用户输入。更具体地说,我的计划是创建一个临时文件,并用一些预先编写的文本填充它,用文本编辑器打开文件,允许用户修改文件内容,在用户退出编辑器后读取文件中的数据,最后在文件结束后删除文件 我似乎已经找到了一种对我有效的方法,但在这一过程中,我尝试了两种不起作用的方法,我想知道确切的原因 考虑以下Python脚本(该脚本的一个稍加修改的版本取自): #/usr/bin/env蟒蛇2 #-*-编码:ascii-*- “”“callvim.py

我最初的目标是通过命令行文本编辑器从Python脚本中获取用户输入。更具体地说,我的计划是创建一个临时文件,并用一些预先编写的文本填充它,用文本编辑器打开文件,允许用户修改文件内容,在用户退出编辑器后读取文件中的数据,最后在文件结束后删除文件

我似乎已经找到了一种对我有效的方法,但在这一过程中,我尝试了两种不起作用的方法,我想知道确切的原因

考虑以下Python脚本(该脚本的一个稍加修改的版本取自):

#/usr/bin/env蟒蛇2
#-*-编码:ascii-*-
“”“callvim.py
演示如何从Python脚本中调用文本编辑器(例如Vim),
包括向编辑器传递输入和从编辑器读取输出。
"""
导入临时文件
导入操作系统
从子流程导入调用
#从shell获取文本编辑器,否则默认为Vim
EDITOR=os.environ.get('EDITOR','vim')
#设置用于填充缓冲区的初始输入
初始消息=“你好,世界!”
#打开一个临时文件进行通信
将tempfile.NamedTemporaryFile(后缀=“.tmp”)作为tf:
#将初始内容写入文件I/O缓冲区
tf.write(初始消息)
#刷新I/O缓冲区以确保数据写入文件
tf.flush()
#用文本编辑器打开文件
调用([EDITOR,tf.name])
#将文件偏移倒带到文件的开头
tf.seek(0)
#将文件数据读入变量
已编辑的_message=tf.read()
#输出数据
打印(已编辑的信息)
到目前为止,我已经尝试在两种不同的环境中运行此脚本:在macOS计算机上(运行macOS 10.12)和在Debian计算机上(运行Debian 8.8)。两台计算机安装了相同(次要)版本的Vim(Vim 7.4)

当我在我的Debian 8(Jessie)机器上用
EDITOR=vim
运行这个脚本时,它会按预期工作。我会收到Vim和一个包含字符串“helloworld!”的缓冲区的提示。在编辑缓冲区以包含字符串“再见世界!”、保存文件并退出Vim之后,我看到控制台上打印了字符串“再见世界!”

当我在macOS 10.12(Sierra)机器上运行相同的脚本时,它似乎不起作用。同样的过程会在屏幕上显示“Hello world!”——就好像文件在编辑前被读取一样

但是,如果在我的Mac电脑上用
EDITOR=nano
运行脚本,那么一切似乎又一次按预期运行了

我使用
tempfile
模块中的不同方法(例如使用
tempfile.TemporaryFile()
tempfile.mkstemp()
)对此脚本进行了一些修改,得到了相同的结果

现在考虑下面的替代脚本:

#/usr/bin/env蟒蛇2
#-*-编码:ascii-*-
“”“callvim.py
演示如何从Python脚本中调用文本编辑器(例如Vim),
包括向编辑器传递输入和从编辑器读取输出。
"""
导入子流程
导入操作系统
#创建一个临时文件并写入一些默认文本
file\u path=“tempfile”
文件句柄=打开(文件路径,“w”)
文件\u handle.write(“Hello world!”)
文件\u handle.close()
#用Vim打开文件
子进程调用([“vim”,文件路径])
#倒带到文件的开头
文件句柄=打开(文件路径“r”)
#从文件中读取数据
数据=文件\句柄.read()
#关闭临时文件
文件\u handle.close()
#删除临时文件
删除(文件路径)
#打印数据
打印(数据)
该脚本避免了使用
tempfile
模块,在两个平台上似乎工作一致


因此,这个脚本可能由于某种原因而失败,这与Vim和
tempfile
Python模块在macOS上如何交互有关。这是怎么回事?

这是因为第二个脚本在调用
vim
之前关闭了文件句柄,然后打开了一个新的句柄,而第一个脚本没有。它与tempfile模块本身无关。此代码按预期工作:

import tempfile, os
from subprocess import call

initial_message = "Hello world!"

tf = tempfile.NamedTemporaryFile(suffix=".tmp", delete=False)
tf.write(initial_message)
tf.close()

call(['vim', tf.name])

tf = open(tf.name, 'r')
edited_message = tf.read()
tf.close()

os.unlink(tf.name)

print(edited_message)
请注意调用
NamedTemporaryFile
中的
delete=False
,它确保在我们第一次关闭文件时不会删除该文件(我们必须在以后使用
os.unlink
手动删除它)


我认为这里发生的事情是,
vim
没有在适当的位置编辑您的文件,而是写入交换文件。保存并退出时,
vim
将原始文件替换为已编辑的文件,使文件句柄指向未编辑的旧文件。有一些方法可以防止
vim
使用交换文件(例如,请参阅),但我不推荐它们。请记住在vim完成其业务后更新您的文件句柄。

可能重复的@Michael看起来肯定是同一个问题,但我接受了这篇文章的解决方案,而另一篇文章没有接受的解决方案。我们还是应该把这个标记为重复的,还是应该用另一种方式来做呢?你接受的答案实际上与另一个问题的答案相同。@Michael是的,我同意。我只是想问,把一个有公认答案的问题和一个没有公认答案的问题联系起来是否更可取。我想你是说这并不重要吧?