15 фишек IPython, которые сделают вашу жизнь проще

автор рубрика
15 фишек IPython, которые сделают вашу жизнь проще

Часто код на Python приходится писать «на коленке» для проверки разных гипотез Data Science. Чтобы это сделать быстро, используют Python REPL или более удобный IPython, который является минималистичным Jupyter Notebook в терминале. В этой статье мы дадим 15 полезных советов по использованию IPython. Читайте у нас: быстрый вызов документации функции, редактор кода без выхода из IPython, поиск функций, вывод переменных сессии, сохранение результатов в Python файле и многое другое.

1. Вывод документации

Это одна из полезных особенностей IPython, которую часто используют на практике. Она позволяет отобразить документацию по любой функции, классу, методу, модулю путем добавления знака ? в начале или в конце. С ее помощью не нужно искать в Интернете каких-то деталей, особенно если библиотеки хорошо задокументированы, например, стандартные библиотеки Python, Scikit-learn, Pandas, TensorFlow и др.

В обычном Python REPL тот же самый функционал достигается встроенной функцией help(). Но это выглядит многословно: нужно написать help, а потом объект заключить в скобки.

Код в IPython для вывода документации выглядит следующим образом:

In [1]: from itertools import chain
In [2]: chain?
Init signature: chain(self, /, *args, **kwargs)
Docstring:     
chain(*iterables) --> chain object

Return a chain object whose .__next__() method returns elements from the
first iterable until it is exhausted, then elements from the next
iterable, until all of the iterables are exhausted.
Type:           type
Subclasses:

2. Вывод исходного кода

Помимо обычной документации, в IPython можно получить исходный код для некоторых функций, методов и классов. Она поможет узнать какие аргументы передаются, в каком порядке, их типы, возвращаемый объект и т.д. Правда, работает не для всех функций (но можно вместо этого использовать %edit, см. №3).

Пример вызова исходного кода в IPython для функции из Scikit-learn:

Signature: train_test_split(*arrays, **options)
Source:   
def train_test_split(*arrays, **options):
    """Split arrays or matrices into random train and test subsets
    Read more in the :ref:`User Guide <cross_validation>`.
    Parameters
    ----------
    *arrays : sequence of indexables with same length / shape[0]
    ## Продолжение документации
    """
    n_arrays = len(arrays)
    if n_arrays == 0:
        raise ValueError("At least one array required as input")
    ## Продолжение кода

3. Магическая команда для редактирования %edit

Когда требуется написать длинную функцию или класс, то используйте магическую команду %edit. Она откроет текстовый редактор, указанный в EDITOR в переменных среды. Там можно писать свой код, а после закрытия IPython выполнит его и вернет в виде строки. Это очень удобно, поскольку не нужно выходить из IPython и создавать новый файл.

Если вы вызовете %edit -p, то IPython попытается открыть редактор с тем же код, что был написан в последний раз использования %edit. Если же вы создали много правок, то вы можете к ним обращаться по номеру, введя %edit_NN, где NN — номер правки. Такие вызовы похожи на систему контроля версий git. Кроме того, с этой магической командой можно редактировать импортированные функции, для этого передайте ей эти функции в качестве аргумента, например, %edit func.

Пример кода для открытия редактора и обращение по номеру в IPython:

In [1]: edit -p
IPython will make a temporary file named: /tmp/ipython_edit_nA09Qk.py
Editing... done. Executing edited code...
hello – it is %edit
Out[1]: "print('hello - it is %edit)\n"

In [2]: edit _1
IPython will make a temporary file named: /tmp/ipython_edit_gy6-zD.py
Editing... done. Executing edited code...
hello - this is a temporary file
IPython version control at work 🙂
Out[2]: "print('hello - this is a temporary file')\nprint('IPython version control at work :)')\n"

4. Поиск по шаблону

Если вы забыли имя какой-либо функции, то используйте поиск по шаблону с помощью знака * и вопросительный знака ? в конце или начале. Например, мы знаем, что у модуля os есть функция для создания директории, но забыли её точное название. Но припоминаем, что в названии содержится dir. Тогда в IPython нахождения всех функций с этим названием будет выглядеть так:

In [1]: import os

In [2]: os.*dir*?
os.__dir__
os.chdir
os.curdir
os.fchdir
os.listdir
os.makedirs
os.mkdir
os.pardir
os.removedirs
os.rmdir
os.scandir
os.supports_dir_fd

5. Отладчик кода

В IPython есть встроенный отладчик кода. Если у вас функция выбрасывает исключение, то с помощью отладчика кода можно проверить значения переменных. Для этого вызовете магическую кодманду %debug.  Здесь не нужно ставить никаких breakpoint.

In [1]: from spool import foo

In [3]: foo(6)
ZeroDivisionError

In [4]: %debug
      4     if n > 5:
      5         y *= -x
----> 6         return y / 0
      7     return y
ipdb> x
5
ipdb> y
-15

6. Автоматическая отладка кода

Если вам нужно проводить отладку код на каждое исключение, то используйте магическую команду %pdb. Чтобы отключить введите ее повторно.

Пример использования отладчика кода с созданной функцией:

In [1]: %pdb
Automatic pdb calling has been turned ON

In [2]: from spool import foo

In [3]: foo(6)
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-3-d07199591eb7> in <module>
----> 1 foo(6)

ZeroDivisionError: division by zero
> spool.py(6)foo()
      4     if n > 5:
      5         y *= -x
----> 6         return y / 0
      7     return y
      8 

ipdb> x
5
ipdb> y
-15

7. Перезагрузка модулей с autoreload и aimport

Воспользуйтесь %autoreload для автоматической перезагрузки всех импортированных модулей или %aimport для конкретного модуля. По умолчанию Python не импортирует второй раз указанные функции, даже если вы перезапустите соответствующие ячейки. Если вы измените код этих функций, Python всё равно продолжит использовать версию с первым импортом.

Поэтому если вы пользуйтесь своим модулем, делает в нем правки, то можете в %aimport указать его в качестве аргумента. Либо перезагружать все с помощью %autoreload. В эту магическую команду можно передавать аргументы, как указано в документации.

In [1]: from spool import foo

In [2]: foo()
Out[2]: 'Hello'

In [3]: %load_ext autoreload

In [4]: %autoreload

In [5]: foo()
Out[5]: 'Bye'

8. Перезапуск предыдущей сессии

Возможно что-то важное вы запускали при предыдущем использовании IPython. И хотите снова посмотреть и запустить код из прошлой сессии, то введите команду %rerun ~1/. Здесь ~1 означает первая сессия перед текущей, а / — выполнение всех строк. Можно и запустить и другие сессии или указать определенные строчки (в документации показаны примеры). Если в предыдущей сессии были исключения, то код выполнится именно до этого момента.

In [1]: a = 10

In [2]: b = a * 10

In [3]: b
Out[3]: 100
# Выходим из IPython
In [1]: %rerun ~1/
=== Executing: ===
a = 10
b = a * 10
b
=== Output: ===

9. Вывод предыдущих строк

Если вы забыли присвоить переменной значение, то используйте выражение var = _. Здесь _ сохраняет вывод последней команды (это также работает в стандартном Python REPL). Результаты всех предыдущих команд сохраняются в переменных _1 (вывод первой команды), _2 (вывод второй команды) и т. д.

In [1]: sum(range(100))
Out[1]: 4950

In [2]: s = _

In [3]: s
Out[3]: 4950

In [4]: sum(range(200))
Out[4]: 19900

In [5]: _
Out[5]: 19900

In [6]: _1
Out[6]: 4950

10. Как вывести все переменные

Вы можете получить список всех переменных из текущей сессии, включая типы данных и их значения с помощью команды %whos.

Вот так выглядит вывод всех переменных в IPython:

In [1]: a = 10

In [2]: b = 'great'

In [3]: def foo(n):
   ...:     return n

In [4]: class Bar:
   ...:     pass

In [5]: b = Bar()

In [6]: %whos
Variable   Type        Data/Info
--------------------------------
Bar        type        <class '__main__.Bar'>
a          int         10
b          Bar         <__main__.Bar object at 0x7f051b5df580>
foo        function    <function foo at 0x7f051b63b9d0>

11. Очистить от отступов и знаков REPL

Если вы копируете код и вам нужно убрать неправильно заданный отступ или символы «>>>» из REPL, то чтобы не редактировать вручную просто скопируйте код и выполните %paste. IPython вставит код из буфера обмена, исправит отступы и/или удалит символы «>>>».

Например, вставим код, который мы использовали из прошлой статьи по форматированию строк f-string в Python:

In [1]: %paste
>>> text = 'world'

>>> 'Hello, %s' % text
>>> 'Hello, {}'.format(text)
>>> f'Hello, {text}'
'Hello, world'

## -- End pasted text --
Out[1]: 'Hello, world'

12. Выполняйте код при запуске IPython

Если вы хотите выполнить какой-то код каждый раз при запуске IPython, просто создайте новый файл в папке автозагрузки (~/.ipython/profile_default/startup/) и добавьте туда свой код. IPython автоматически выполнит любые файлы, найденные в этой папке. Это удобно, если вы хотите импортировать некоторые модули, которые используете постоянно. Не рекомендуем помещать туда много кода, поскольку время запуска IPython будет медленнее, но рекомендуем использовать профили, о чем дальше.

13. Используйте разные профили

Возможно, у вас есть набор модулей, которые вы хотите импортировать, и настройки, которые нужно установить в конкретной ситуации. Например, сейчас вы сосредоточены на задачах машинного обучения (machine learning) и вам нужна библиотека Scikit-learn, Pandas, NumPy или нужна еще визуализация с Matplotlib. Тогда создайте под каждую задачу разные профили, в котором можно импортировать при запуски библиотеки.

Профили похожи на разные учетные записи пользователей для IPython — каждый из них имеет свой собственный файл конфигурации и папку автозагрузки. Ищите созданные профили в папке ~/.ipython.

Для создания профиля в командой строке, выполните команду:

ipython profile create profilename

где вместо profilename выберите свое название профиля.

А для запуска укажите его в аргументе --profile:

ipython --profile=profilename

14. Делитесь свои кодом

Если вы хотите поделиться своим кодом с кем-то, используйте магическую команду %pastebin и укажите номер строк, которые нужно показать. IPython создаст pastebin (что-то похожее на GitHub gist), вставит выбранные строки и вернет ссылку, которую вы можете кому-то отправить. Учтите, что срок действия истекает через 7 дней.

In [1]: a = 10

In [2]: b = a * 90

In [3]: c = 100

In [4]: %pastebin 1-2
Out[4]: 'http://dpaste.com/3ZTUPFDGH'

15. Сохраняйте сессию в файл

Вы можете сохранить сессию в Python-файл с помощью команды %save. Это очень полезно, если у вас есть рабочий код и вы хотите продолжить с ним работать в текстовом редакторе, не копируя все строки и затем удаляя все In и Out.

Пример того, как сохранить сессию IPython в файл Python:

In [1]: a = 10

In [2]: b = a * 90

In [3]: c = 100

In [6]: %save my_file.py 1-3

Также смотрите в нашем видеоролике об основах работы с Jupyter Notebook:

 

А о том, как на практике решать прикладные задачах Data Science на языке Python вы узнаете на наших курсах в лицензированном учебном центре обучения и повышения квалификации Data Scientist’ов и IT-специалистов в Москве.

Комментировать