Python Jupyter:编写一个自定义魔法,修改它所在单元格的内容';在哪

Python Jupyter:编写一个自定义魔法,修改它所在单元格的内容';在哪,python,ipython-notebook,jupyter,jupyter-notebook,Python,Ipython Notebook,Jupyter,Jupyter Notebook,在Jupyter笔记本中,有一些内置的魔法可以改变笔记本电池的内容。例如,%load魔术将当前单元格的内容替换为文件系统中的文件内容 如何编写具有类似功能的自定义魔术命令 到目前为止,我已经打印了一些东西到stdout def tutorial_asset(line): print('hello world') def load_ipython_extension(ipython): ipython.register_magic_function(tutorial_asset

在Jupyter笔记本中,有一些内置的魔法可以改变笔记本电池的内容。例如,
%load
魔术将当前单元格的内容替换为文件系统中的文件内容

如何编写具有类似功能的自定义魔术命令

到目前为止,我已经打印了一些东西到stdout

def tutorial_asset(line):
    print('hello world')


def load_ipython_extension(ipython):
    ipython.register_magic_function(tutorial_asset, 'line')
我可以用
%load\u ext tutorial\u asset
加载它。但从那以后我就迷路了

[编辑]:

我找到了一种访问交互式shell实例的方法:

  @magics_class
  class MyMagics(Magics):

      @line_magic
      def tutorial_asset(self, parameters):
          self.shell
self.shell
对象似乎可以完全访问笔记本中的单元格集,但我能找到的修改单元格的唯一方法是执行
self.shell.set\u next\u输入('print(“hello world”))
。这是不够的,因为在Jupyter笔记本中,该输入单元格被跳过,它不会覆盖该输入单元格,而是在其后创建一个新的输入单元格

这很好,但如果我再次运行笔记本,它会创建另一个输入单元,并加载相同的文件,这很烦人。我可以只加载一次吗?比如,通过检查内容是否已经在下一个单元格中?

编辑:进一步挖掘后,我发现当前版本的笔记本无法同时加载这两个内容

嗯,这有点棘手。。。查看IPython代码,如果要替换单元格,则需要使用
set\u next\u input
;如果确实要运行某些代码,则需要使用
run\u cell
。然而,我不能让两者同时工作——看起来
set\u next\u input
总是赢

深入代码,web前端支持
set\u next\u input
。但是,输出(和so输出将始终作为默认操作清除)。要做得更好,需要对ipykernel进行修补

因此,我拥有的最好的代码是使用jupyter笔记本4.2.1版的以下代码:

from __future__ import print_function
from IPython.core.magic import Magics, magics_class, line_magic

@magics_class
class MyMagics(Magics):

    @line_magic
    def lmagic(self, line):
        "Replace current line with new output"
        raw_code = 'print("Hello world!")'
        # Comment out this line if you actually want to run the code.
        self.shell.set_next_input('# %lmagic\n{}'.format(raw_code), replace=True)
        # Uncomment this line if you want to run the code instead.
        # self.shell.run_cell(raw_code, store_history=False)

ip = get_ipython()
ip.register_magics(MyMagics)

这将为您提供一个神奇的命令
lmagic
,它将替换当前单元格或运行
raw\u code
,具体取决于您注释掉的代码位。

这项技术是为我创建一个新单元格,而不是修改当前单元格。我遗漏了什么吗?@ajp619这是一个相当古老的注释,但无论如何,它正在替换,因为
replace=True
位。如果将其更改为False,它将创建一个新单元。Jupyter Notebook v6.4.0仍然一次只能执行一个,但Jupyter Lab v3.0.16可以同时替换和运行。