Emacs中的Python: __name__ == '__main__',但似乎不是
我在emacs里写Python代码,但有时候emacs里的Python解释器让我感到意外。
如果我在emacs的一个窗口里写
print()
print(__name__)
print(__name__=='__main__')
if __name__ == '__main__':
print("indeed")
然后让我emacs启动一个解释器并运行这个窗口里的内容,我得到的结果是
Python 3.3.5 (default, Mar 18 2014, 02:00:02)
[GCC 4.2.1 20070831 patched [FreeBSD]] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
>>>
__main__
True
>>>
(这里的__main__
和True
都是打印语句的输出;Python窗口总是显示>>>
,然后立刻打印结果。我知道这一点,这不是问题。)
在命令行里,运行python
和python -i
都会如预期显示'indeed'。
那么,emacs是怎么做到在评估__name__=='__main__'
时返回True
,但却不执行if __name__ == '__main__':
里面的内容的呢?我该怎么重新配置它,让它不再这样做呢?
3 个回答
一旦你启动了Python的命令行界面,你可以很简单地覆盖(也就是重新定义)一个变量:
__name__ = 'repl'
这样做可以防止在后续使用 C-c C-c
命令时,任何 if __name__=='__main__':
这部分代码被执行。
这个“功能”永远不会过时。试着使用
__name__=='__main__':
在运算符之间不要留空格。
这样的话,python.el 就不会跳过它。所以看看你的代码格式化工具。
正如@Wooble在评论中提到的,这可能是python.el
的问题:C-c C-c
会运行
python-shell-send-buffer
这个功能:
python-shell-send-buffer是一个在`python.el`中的交互式编译Lisp函数。
(python-shell-send-buffer &可选 ARG)
将整个缓冲区的内容发送到一个Python进程。如果加上前缀ARG,就可以执行被
"if __name__=='__main__':"
包围的代码块。
也就是说,要打印“确实”,你需要加上前缀C-u C-c C-c
。
问:我试着查看python.el的代码,但仍然不确定它是如何以及在哪里做到这一点的。你能解释一下吗?这样我就可以修改默认行为。
要了解C-c C-c
在你这边的作用,可以打开一个Python文件,然后输入M-x describe-key RET
,接着按C-c C-c
(实际上就是按下这些键)。默认情况下,它会在python.el
中运行python-shell-send-buffer
这个功能。你可以重新定义这些按键,让它们调用带参数的函数,这样C-c C-c
就会像C-u C-c C-c
那样,能够运行"if __name__=='__main__':"
部分:
;; Make C-c C-c behave like C-u C-c C-c in Python mode
(require 'python)
(define-key python-mode-map (kbd "C-c C-c")
(lambda () (interactive) (python-shell-send-buffer t)))