【发布时间】:2014-10-29 11:00:34
【问题描述】:
我正在尝试运行 Python 代码以使用 Emacs 进行测试和调试。我应该如何调试和运行 *.py 文件中的代码?我尝试使用 M-x compile commands 。使用M-x compile,我得到了一个崩溃的编译缓冲区(它说 Python 正在编译,但是什么也没发生)。
【问题讨论】:
我正在尝试运行 Python 代码以使用 Emacs 进行测试和调试。我应该如何调试和运行 *.py 文件中的代码?我尝试使用 M-x compile commands 。使用M-x compile,我得到了一个崩溃的编译缓冲区(它说 Python 正在编译,但是什么也没发生)。
【问题讨论】:
如果您使用 emacs24,这应该是默认设置(在 emacs23 中您需要 python.el,而不是 python-mode.el):
在 python 缓冲区中:
默认的python shell是“python”,如果你需要使用ipython你可以在你的.emacs中使用这个conf
(setq
python-shell-interpreter "ipython"
python-shell-interpreter-args "--colors=Linux --profile=default"
python-shell-prompt-regexp "In \\[[0-9]+\\]: "
python-shell-prompt-output-regexp "Out\\[[0-9]+\\]: "
python-shell-completion-setup-code
"from IPython.core.completerlib import module_completion"
python-shell-completion-module-string-code
"';'.join(module_completion('''%s'''))\n"
python-shell-completion-string-code
"';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
当然,前提是你的系统中安装了 ipython :)
ipython>=5 具有自动完成功能,它会破坏 emacs 子 shell,您可以通过更改此行来解决此问题
python-shell-interpreter-args "--colors=Linux --profile=default"
并添加--simple-prompt。
它可以让你正确地看到 ipython,但由于某种原因我还没有得到 emacs 中的自动完成功能不像以前那样有效。
【讨论】:
在 Emacs 中打开 python 文件后,您需要使用以下命令启动 python 进程:
M-x run-python 或 C-c C-p,这会创建一个劣质的 python shell 缓冲区。此缓冲区将通过水平拆分创建,活动缓冲区将是包含 python 文件的缓冲区。
然后你可以做C-c C-c,它将当前的python缓冲区发送到下面的劣质python shell。这是您将看到 Python 文件的输出的地方。
要在 python 文件缓冲区和劣质 python shell 缓冲区之间切换,可以使用C-x o。
如果您不小心关闭了其中一个缓冲区,您可以使用C-x C-<left_arrow> 和C-x C-<right_arrow> 在缓冲区之间切换,并像Aaron Hall 中提到的那样对python 缓冲区执行操作。
注意:
在没有任何扩展的情况下运行 GNU Emacs 26.2。
没有定义if (__name__ == '__main__'):块
【讨论】:
在我看来,M-! 和 M-& 被低估了。通常你只想启动你正在处理的当前脚本,不需要让事情复杂化。
当然,您可以使用M-x compile,只要您不必提供交互式输入。如果您确实必须提供交互式输入,M-x shell 就是您的朋友。
如果您想一键运行,请查看 F3 和 F4 录制键盘宏并重播(宏也可以绑定到键,例如 F5)。
在每一种情况下,都没有发生“魔法”。 Emacs 不知道如何“编译”或“运行”python 脚本。您必须提供/覆盖一个合理的命令行调用,例如:
Compile Command: ipython <yourscriptname>.py
python 子shell 在 REPL 开发风格有意义的地方很酷,但至少在 Windows matplotlib、tkinter 和其他必须处理 Windows 消息循环的库上往往会在显示 GUI 元素时阻塞/挂起。
【讨论】:
如何使用 Emacs 运行 Python 代码?
我正在运行 Emacs 26,vanilla dev 版本(从Savannah 克隆的源代码自行编译)。
(请注意,在emacs docs中,我们通常会看到,例如,Ctrl-c表示为C-c)
在 Python 模式下(我通常通过使用 Cx Cf 进入以“查找”以 .py 结尾的(可能是新的)文件),您可以启动 Python shell,然后执行缓冲区的if __name__ == '__main__': :
C-c C-p(执行run-python以创建具有Inferior Python主要模式,Shell-Compile次要模式的shell)
C-u C-c C-c(执行带有前缀参数的python-shell-send-buffer)
我们需要前缀参数来将 if __name__ == '__main__': 块发送到劣质 Python shell。
我们可以看到所有的Ctrl-c命令用Ctrl-c ?
C-c C-c python-shell-send-buffer C-c C-d python-describe-at-point C-c C-f python-eldoc-at-point C-c C-j imenu C-c C-l python-shell-send-file C-c C-p run-python C-c C-r python-shell-send-region C-c C-s python-shell-send-string C-c C-t Prefix Command C-c C-v python-check C-c C-z python-shell-switch-to-shell C-c < python-indent-shift-left C-c > python-indent-shift-right C-c C-t c python-skeleton-class C-c C-t d python-skeleton-def C-c C-t f python-skeleton-for C-c C-t i python-skeleton-if C-c C-t m python-skeleton-import C-c C-t t python-skeleton-try C-c C-t w python-skeleton-while
检查 python-shell-send-buffer 的帮助(通过单击它),我们看到:
python-shell-send-buffer is an interactive compiled Lisp function in ‘python.el’. (python-shell-send-buffer &optional SEND-MAIN MSG) Send the entire buffer to inferior Python process. When optional argument SEND-MAIN is non-nil, allow execution of code inside blocks delimited by "if __name__== '__main__':". When called interactively SEND-MAIN defaults to nil, unless it’s called with prefix argument. When optional argument MSG is non-nil, forces display of a user-friendly message if there’s no process running; defaults to t when called interactively.
根据docs C-u 是一个前缀参数 - 似乎是最通用的一个。
让我们避免使用前缀参数 C-u 的解决方法是使用括号:
if (__name__ == '__main__'):
main()
而不是通常的:
if __name__ == '__main__':
main()
然后C-c C-c自己执行main函数。
【讨论】:
C-c C-c 的C-u 前缀。文档字符串说“这会将 if name == 'main' 的 Python 习语转义为 false 以避免意外执行代码”,但执行代码才是重点的C-c C-c。你知道是否有一种emacs方法可以避免C-u前缀而不是将Python语法更改为非标准? C-c C-c 比 C-u C-c C-c 快得多...