返回介绍

进阶篇:定制基于 IPython 的交互解释环境

发布于 2025-04-20 18:52:17 字数 2989 浏览 0 评论 0 收藏

之前在介绍 Flask 0.11 的命令行接口时,实现了在 Flask 应用中使用基于 IPython 的交互解释环境的例子。这种模式在日常开发中非常有意义:我们不再需要每次进入交互环境之后都要 import 一大堆模块,而是直接使用它们。本节将继续深入讲解定制 IPython,下面就基于文件托管服务的代码实现一个这样的环境(shell.py)。

首先通过 readline 模块添加记录历史记录的函数:

import atexit
  
def hook_readline_hist():
    try:
       import readline
    except ImportError:
        return
  
    # 指定一个存储历史记录的文件地址
    histfile=os.environ['HOME']+'/.web_develop_history'
    readline.parse_and_bind('tab:complete')
    try:
        readline.read_history_file(histfile)
    except IOError:
        pass # 第一次使用时文件还不存在
    def savehist():
        try:
            readline.write_history_file(histfile)
        except:
            print 'Unable to save Python command history'
    atexit.register(savehist) # 添加退出时保存历史记录的钩子

接着添加环境的 Banner 信息,这非常重要,添加合理的 Banner 信息能让开发者直观地分辨开发环境和正式环境:

def get_banner():
    from app import app
    color_tmpl='\x1b[{}m{}\x1b[0m'
    return color_tmpl.format(
        *(32, 'Development shell, do whatever you want.')
        if app.debug else (
            35, 'Production shell, use it carefully!'))

“\x1b[COLORmTEXT\x1b[0m”是 ANSI 转义码(http://ascii-table.com/ansi-escape-sequences.php )中提供的打印带颜色文本的方法,其中 30~37 是文本颜色,40~47 是背景颜色,32 表示绿色,35 表示品红色。

IPython 的设置如下:

from IPython.terminal.prompts import Prompts, Token
from IPython.terminal.ipapp import TerminalIPythonApp
from IPython.terminal.interactiveshell import TerminalInteractiveShell
   
    
class MyPrompt(Prompts):
    def in_prompt_tokens(self, cli=None):# default
        return [
            (Token.Prompt, 'In<'),
            (Token.PromptNum, str(self.shell.execution_count)),
            (Token.Prompt, '>:'),
        ]
    def out_prompt_tokens(self):
        return [
            (Token.OutPrompt, 'Out<'),
            (Token.OutPromptNum, str(self.shell.execution_count)),
            (Token.OutPrompt, '>:'),
        ]
     
        
class MyIPythonApp(TerminalIPythonApp):
    def init_shell(self):
        self.shell=TerminalInteractiveShell(
            prompts_class=MyPrompt, highlighting_style='emacs',
            display_banner=False, profile_dir=self.profile_dir,
            ipython_dir=self.ipython_dir, banner1=get_banner(), banner2='')
        self.shell.configurables.append(self)
   
app=MyIPythonApp.instance()
app.initialize()
app.shell.user_ns.update(user_ns)
sys.exit(app.start())

TerminalInteractiveShell 接受一系列参数,其中 MyPrompt 类把提示符改成了如下格式:

In <1>:

highlighting_style 可以指定语法高亮的 Pygments 样式的名字,全部样式可以通过如下命令获得:

import pygments
list(pygments.styles.get_all_styles())

从 IPython 5.0 开始,TerminalInteractiveShell 将使用第三方的 prompt-toolkit 作为新的终端接口,它提供如下特性:

  • 纯 Python 实现。
  • 通过 Pygments 库,支持语法高亮。
  • 支持 Emacs/VIM 的键盘绑定。
  • 轻量,只依赖 Pygments、six 和 wcwidth 就支持了 2.6 到 3.5 的 Python 版本。

这个库的作者还写了另外一个 REPL 的实现 ptpython。如果你想构建跨平台、接口简单、易移植的交互命令行和终端应用,prompt-toolkit 将是最好的选择。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。