Магия Юпитера, определенная из метода экземпляра - PullRequest
0 голосов
/ 26 августа 2018

Я пишу класс, который отправляет слабые сообщения пользователям после завершения процессов. Я подумал, что было бы полезно предоставить магию Jupyter, чтобы пользователи могли получать уведомления при выполнении ячейки.

Класс уже предоставляет декоратор, поэтому я решил, что я просто оберну выполнение ячейки в декорированную функцию.

from IPython.core.magic import register_cell_magic
from IPython import get_ipython

import functools

class MyClass(object):

    def decorate(self, f):
        @functools.wraps(f)
        def wrapped(*args, **kwargs):
            r = f(*args, **kwargs)
            print('Send a message here!')
            return r
        return wrapped

    @register_cell_magic
    def magic(self, line, cell):
        ip = get_ipython()
        @self.decorate
        def f():
            return ip.run_cell(cell)
        return f()

Итак, я бы сделал:

obj = MyClass()

# ----- NEW CELL
%%obj.magic
'''do some stuff'''

Но я получаю

>> UsageError: Cell magic `%%obj.magic` not found.

Я обнаружил, что магия зарегистрирована под своим именем (выше, magic), поэтому %%magic работает. Но тогда все аргументы перепутаны, потому что в миксе нет self.

Я хочу, чтобы магия была методом экземпляра, чтобы можно было использовать конфигурацию (установленную в __init__). Есть ли способ сделать это?

Вот пара хакерских решений, которые я не хочу реализовывать, если мне действительно не нужно:

  1. Зарегистрировать обычную функцию с экземпляром в качестве аргумента. Я не хочу добавлять эту строку кода в блокнот, Я хочу использовать метод экземпляра .
  2. Зарегистрируйте обычную функцию, которая создает экземпляр на лету.

1 Ответ

0 голосов
/ 26 августа 2018

Это лучшее, что я могу придумать, и это # ​​1 в списке вещей, которые я не хотел делать.

from IPython.core.magic import register_cell_magic
from IPython import get_ipython

import functools

class MyClass(object):

    def decorate(self, f):
        @functools.wraps(f)
        def wrapped(*args, **kwargs):
            r = f(*args, **kwargs)
            print('Send a message here!')
            return r
        return wrapped


    def register_magic(self):
        @register_cell_magic
        def magic(line, cell):
            ip = get_ipython()
            @self.decorate
            def f():
                return ip.run_cell(cell)
            return f()

Тогда

obj = MyClass()
obj.register_magic()

# ------
%%magic
...
...