[英]Click on Python and File in MenuBar of a Qt windows not working on Mac OS
[英]Editing temporary file with Vim in Python subprocess not working as expected on Mac OS
我最初的目標是通過Python腳本中的命令行文本編輯器獲取用戶輸入。 更具體地說,我的計划是創建一個臨時文件並用一些預先寫好的文本填充它,用文本編輯器打開文件並允許用戶修改文件內容,在用戶退出后從文件中讀取數據編輯器,然后最后刪除文件后全部刪除。
我似乎已經找到了一種方法來做到這一點,這對我有用,但一路上我嘗試了幾種不起作用的方法,我想知道究竟為什么。
考慮以下Python腳本(從這篇文章中略微修改的腳本版本):
#!/usr/bin/env python2
# -*- encoding: ascii -*-
"""callvim.py
Demonstrates calling a text-editor (e.g. Vim) from within a Python script,
including passing input to the editor and reading output from the editor.
"""
import tempfile
import os
from subprocess import call
# Get the text editor from the shell, otherwise default to Vim
EDITOR = os.environ.get('EDITOR','vim')
# Set initial input with which to populate the buffer
initial_message = "Hello world!"
# Open a temporary file to communicate through
with tempfile.NamedTemporaryFile(suffix=".tmp") as tf:
# Write the initial content to the file I/O buffer
tf.write(initial_message)
# Flush the I/O buffer to make sure the data is written to the file
tf.flush()
# Open the file with the text editor
call([EDITOR, tf.name])
# Rewind the file offset to the beginning of the file
tf.seek(0)
# Read the file data into a variable
edited_message = tf.read()
# Output the data
print(edited_message)
到目前為止,我已嘗試在兩個不同的環境中運行此腳本:在macOS計算機(運行macOS 10.12)和Debian計算機(運行Debian 8.8)上運行。 兩台計算機都安裝了相同(次要)的Vim版本(Vim 7.4)。
當我在Debian 8(Jessie)機器上使用EDITOR=vim
運行此腳本時,它按預期工作。 我被Vim和一個包含字符串“Hello world!”的緩沖區提示。 在編輯緩沖區以包含字符串“Goodbye world!”,保存文件並退出Vim之后,我看到字符串“Goodbye world!” 打印到控制台。
當我在我的macOS 10.12(Sierra)機器上運行相同的腳本時,它似乎不起作用。 同樣的程序導致“Hello world!” 在屏幕上顯示 - 就像在編輯文件之前正在讀取文件一樣。
但是如果在我的Mac上使用EDITOR=nano
運行腳本,那么一切似乎都按預期工作。
我嘗試使用tempfile
模塊中的不同方法(例如使用tempfile.TemporaryFile()
和tempfile.mkstemp()
)對此腳本進行了一些變化,結果相同。
現在考慮以下替代腳本:
#!/usr/bin/env python2
# -*- encoding: ascii -*-
"""callvim.py
Demonstrates calling a text-editor (e.g. Vim) from within a Python script,
including passing input to the editor and reading output from the editor.
"""
import subprocess
import os
# Create a temporary file and write some default text
file_path = "tempfile"
file_handle = open(file_path, "w")
file_handle.write("Hello world!")
file_handle.close()
# Open the file with Vim
subprocess.call(["vim", file_path])
# Rewind to the beginning of the file
file_handle = open(file_path, 'r')
# Read the data from the file
data = file_handle.read()
# Close the temporary file
file_handle.close()
# Delete the temporary file
os.remove(file_path)
# Print the data
print(data)
這個避免使用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
完成業務后更新文件句柄。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.