如何用自己的横幅调用`IPython.start_ipython()`?

时间:2021-03-28 20:48:26

What works

When calling IPython.embed(), one can pass banner1, banner2 or header to customize the message that appears before the interactive session, like this:

调用IPython.embed()时,可以传递banner1,banner2或header来自定义在交互式会话之前出现的消息,如下所示:

import IPython
IPython.embed(banner2="*** Welcome! ***")

With the result:

结果如下:

Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
Type "copyright", "credits" or "license" for more information.

IPython 3.2.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

*** Welcome! ***
In [1]: 

What doesn't work

When using IPython.start_ipython(), instead of IPython.embed() in the invocation above, I couldn't find any parameters that would influence the banner, except display_banner=False to omit the it entirely.

在上面的调用中使用IPython.start_ipython()而不是IPython.embed()时,我找不到任何会影响横幅的参数,除了display_banner = False以完全省略它。

The best I could do was to mangle argv, to change the configuration, like:

我能做的最好的事情是修改argv,改变配置,如:

import sys, IPython
argv = (
    sys.argv[1:] + 
    ['--TerminalInteractiveShell.banner2=*** Welcome! ***']
)
IPython.start_ipython(argv=argv)

This is usable but looks contrived.

这是可用的,但看起来很做作。

I suppose I could also inherit from IPython.ipapp.TerminalInteractiveShell in my code and override .banner1 or .banner2, but this feels like overkill.

我想我也可以在我的代码中继承IPython.ipapp.TerminalInteractiveShell并覆盖.banner1或.banner2,但这感觉就像是矫枉过正。

The Question

All I want is a way to pass banner2 into IPython.start_ipython().

我想要的只是将banner2传递给IPython.start_ipython()的方法。

Is there a more straightforward way?

有更简单的方法吗?

More Technical details

The use case is to create a script that starts an IPython console session with some pre-defined variables for controlling an application with a fairly involved setup. And explain how to use the setup.

用例是创建一个脚本,该脚本使用一些预定义的变量启动IPython控制台会话,以便通过相当复杂的设置来控制应用程序。并解释如何使用设置。

Something like:

import sys, myapp, IPython

explain_usage_of_session = """
You can use session.blah() to frobnicate the foobaringo
"""

session = myapp.MyComplicatedSessionFactory(including=
    configuration.params(from_file))

sys.exit(
    IPython.start_ipython(user_ns=dict(session=session),
                          banner2=explain_usage_of_session)
)

Constraints

The more specific use-case is that this script is being generated automatically by buildout's zc.recipe.egg, which locates IPython.start_ipython using IPython [console_scripts] entry point, so I'm limited in the amount of customization I can actually pass into the script, and I can't use IPython.embed() directly.

更具体的用例是这个脚本是由buildout的zc.recipe.egg自动生成的,它使用IPython [console_scripts]入口点定位IPython.start_ipython,所以我可以实际传入的自定义数量有限脚本,我不能直接使用IPython.embed()。

The super duper plus specific use-case is that I'm actually using anybox.recipe.odoo, which wraps zc.recipe.egg. The end result is that I'm even more limited in how the script is built.

超级duper加上特定的用例是我实际上使用的是包装zc.recipe.egg的anybox.recipe.odoo。最终的结果是我对脚本的构建方式更加有限。

Basically I can just set the parameters that are passed into IPython.start_ipython() call as with the arguments option of zc.recipe.egg, and nothing else. In particular, I can't use the initialization option of zc.recipe.egg.

基本上我可以像zc.recipe.egg的arguments选项一样设置传递给IPython.start_ipython()调用的参数,而不是其他任何东西。特别是,我不能使用zc.recipe.egg的初始化选项。

And I'd rather not have to write my own entry-point.

而且我宁愿不必写自己的入口点。

1 个解决方案

#1


2  

As @Thomas K said, you can create an IPython.Config instance and set the banner2:

正如@Thomas K所说,你可以创建一个IPython.Config实例并设置banner2:

from IPython import start_ipython
from traitlets.config.loader import Config

c = Config()
c.TerminalInteractiveShell.banner2 = '*** Welcome! ***'

start_ipython(config=c)

The result:

$ python start_with_banner.py
Python 2.7.11+ (default, Mar 30 2016, 21:00:42) 
Type "copyright", "credits" or "license" for more information.

IPython 2.4.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

*** Welcome! ***
In [1]: 

Ftr: the Config constructor accepts kwargs:

Ftr:Config构造函数接受kwargs:

c = Config(TerminalInteractiveShell={'banner2': '*** Welcome! ***'})

Hth, dtk

Update: For versions before ipython 5.x, you could directly from IPython import Config.

更新:对于ipython 5.x之前的版本,您可以直接从IPython导入配置。

#1


2  

As @Thomas K said, you can create an IPython.Config instance and set the banner2:

正如@Thomas K所说,你可以创建一个IPython.Config实例并设置banner2:

from IPython import start_ipython
from traitlets.config.loader import Config

c = Config()
c.TerminalInteractiveShell.banner2 = '*** Welcome! ***'

start_ipython(config=c)

The result:

$ python start_with_banner.py
Python 2.7.11+ (default, Mar 30 2016, 21:00:42) 
Type "copyright", "credits" or "license" for more information.

IPython 2.4.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

*** Welcome! ***
In [1]: 

Ftr: the Config constructor accepts kwargs:

Ftr:Config构造函数接受kwargs:

c = Config(TerminalInteractiveShell={'banner2': '*** Welcome! ***'})

Hth, dtk

Update: For versions before ipython 5.x, you could directly from IPython import Config.

更新:对于ipython 5.x之前的版本,您可以直接从IPython导入配置。