如何启用Python REPL的自动补全并允许换行制表符
我现在在 ~/.pythonrc
文件里设置了一些内容,以便在 Python 的交互式环境中启用自动补全功能:
# Autocompletion
import rlcompleter, readline
readline.parse_and_bind('tab:complete')
但是,当我在新的一行开始时按 tab
(比如在一个 for 循环内部),我得到的是一堆建议,而不是一个 tab
。
理想情况下,我希望只有在输入了非空白字符后,才会出现建议。
在 ~/.pythonrc
中实现这个功能简单吗?
1 个回答
34
你可以直接使用IPython。它有自动补全和自动缩进的功能,特别适合处理循环或函数定义。比如说:
# Ipython prompt
In [1]: def stuff(x):
...: |
# ^ cursor automatically moves to this position
要安装它,你可以使用pip
:
pip install ipython
如果你还没有安装pip
,可以按照这个页面上的说明来安装。在python 3.4及以上版本中,pip
是默认安装的。
如果你是在Windows系统上,可以去这个页面下载IPython的安装包(还有很多其他可能难以安装的Python库)。
不过,如果因为某种原因你无法安装IPython,Brandon Invergo创建了一个Python启动脚本,这个脚本为Python解释器添加了几个功能,其中就包括自动缩进。他将这个脚本以GPL v3的协议发布,并在这里提供了源代码。
我把处理自动缩进的代码复制在下面。为了让它在我的Python 3.4解释器上正常工作,我在第11行添加了indent = ''
。
import readline
def rl_autoindent():
"""Auto-indent upon typing a new line according to the contents of the
previous line. This function will be used as Readline's
pre-input-hook.
"""
hist_len = readline.get_current_history_length()
last_input = readline.get_history_item(hist_len)
indent = ''
try:
last_indent_index = last_input.rindex(" ")
except:
last_indent = 0
else:
last_indent = int(last_indent_index / 4) + 1
if len(last_input.strip()) > 1:
if last_input.count("(") > last_input.count(")"):
indent = ''.join([" " for n in range(last_indent + 2)])
elif last_input.count(")") > last_input.count("("):
indent = ''.join([" " for n in range(last_indent - 1)])
elif last_input.count("[") > last_input.count("]"):
indent = ''.join([" " for n in range(last_indent + 2)])
elif last_input.count("]") > last_input.count("["):
indent = ''.join([" " for n in range(last_indent - 1)])
elif last_input.count("{") > last_input.count("}"):
indent = ''.join([" " for n in range(last_indent + 2)])
elif last_input.count("}") > last_input.count("{"):
indent = ''.join([" " for n in range(last_indent - 1)])
elif last_input[-1] == ":":
indent = ''.join([" " for n in range(last_indent + 1)])
else:
indent = ''.join([" " for n in range(last_indent)])
readline.insert_text(indent)
readline.set_pre_input_hook(rl_autoindent)