自动运行Python时出现“读取行时EOF”错误

4 投票
4 回答
1976 浏览
提问于 2025-04-17 22:07

我在我的 .vimrc 文件里加了一行代码

map <F4> :w !python<cr>

当我打开 gvim 编辑一个没有命名的 Python 文件时,里面只有两行内容

x=input("which one do you like ? ")
print(x)

我按下 F4,结果出现了 EOF when reading a line 的错误,我该怎么解决呢?

当你添加 map <F4> :w<cr>:!python %<cr> 或者 imap <F4> <Esc>:w <cr>:!python %<cr> 这段代码时,它只能让有名字的文件运行,如果是没有名字的文件,这个设置就不管用了,我该怎么让没有名字的文件也能运行呢?

enter image description here

4 个回答

1

有一种方法可以在不使用临时文件的情况下做到这一点,可以用一个小的辅助函数来实现:

function! GetContentsForPython()
    let contents = join(getline(1,'$'), "\n")
    let res = ''
    for l in split(contents, '\n')
        if len(l)
            let res = res . l . ';' 
        endif
    endfor
    let res = '"' . escape(res, '"') . '"'
    return res
endfunction

noremap <f4> :!python -c <c-r>=GetContentsForPython()<cr><cr>

这个方法会获取当前缓冲区的内容,并把换行符替换成分号,这样你就可以用下面的方式执行它:

python -c "print 'hello'"

可能还有更好的方法来实现这个功能,但对我来说,这个方法是有效的。

3

我觉得问题出在input()这一行。Python在等待输入,但找不到任何东西。它到处找,结果只发现了一个文件结束符(EOF)。

4

因为你的设置里有 :w,我猜你是想要直接在插入模式下运行脚本,或者在运行之前先保存一下。

在 vim 里,多个命令之间需要用分隔符,比如 <bar>(也就是 |),或者在命令之间和之后使用 <CR>(回车键)。

你可以把下面的两个设置放到你的 .vimrc 文件里,这样无论你是在普通模式还是插入模式下,按 F4 都能满足你的需求。

如果你在普通模式下,可以使用 map

map <F4> :w<cr>:!python %<cr>

而在插入模式下,你需要用 imap,并且按一下 Esc 来退出插入模式:

imap <F4> <Esc>:w <cr>:!python %<cr>
5

@benjifisher的回答是对的。问题出在输入(函数)上。

:w !python这个命令是把程序通过标准输入(stdin)传给python(基本上和

echo 'input("x")' | python

在命令行中运行是一样的,但也会失败)。但是,input()试图从标准输入读取数据,而此时python已经从标准输入读取了程序,标准输入还在尝试从管道中读取。然而,管道已经到达末尾,不会再有新数据。所以,input()只能读取到文件结束符(EOF)。

为了确认python确实在从标准输入读取数据,我们可以查看:h :w_c,这会显示文件被传递给命令的标准输入,而这个命令在这里是python。

                                                        :w_c :write_c
:[range]w[rite] [++opt] !{cmd}
                        Execute {cmd} with [range] lines as standard input
                        (note the space in front of the '!').  {cmd} is
                        executed like with ":!{cmd}", any '!' is replaced with
                        the previous command :!.

如果缓冲区里有一些不是从标准输入读取的内容,你的映射就能正常工作。

举个例子,如果未命名的缓冲区包含

print(42)

在vim中运行命令:w !python会打印出42。

所以问题并不是映射失败。问题在于你的程序不知道怎么获取输入。解决办法是使用一个命名文件,或者不要在vim中编写交互式程序。可以使用python解释器来处理这类情况。

撰写回答