Ipython: Как узнать путь к текущему файлу ipynb из IPython?

Созданный на 5 янв. 2017  ·  15Комментарии  ·  Источник: ipython/ipython

Есть ли способ выяснить текущий файл ipynb из iPython?

Вариант использования: я хочу запускать симуляции из IPython. Чтобы все было задокументировано, я хочу скопировать записную книжку IPython в папку результатов, в идеале из IPython.

Поиск в Интернете по этой проблеме показал, что такая функция вызывает большой интерес, но все решения, представленные на stackoverflow, казались немного хакерскими. Или это уже реализовано?

Самый полезный комментарий

Простите, но с этим:

!echo %cd% # under windows
!pwd # under linux/mac

вы получаете нужную информацию.
Чтобы повторно использовать его, просто выполните:

myInfo01 = !echo %cd% # under windows
myInfo02 = !pwd # under linux/mac

Все 15 Комментарий

Это невозможно, не без взлома, который не будет работать (отображение Javascript, выполняющего код Python).

Вот несколько причин, по которым ядро ​​(в данном случае IPython):

  • может не запускаться из одного файла
  • даже если один файл, файл не может быть записной книжкой.
  • даже если ноутбук, ноутбук не может быть в файловой системе.
  • даже если в файловой системе, это может быть не на той же машине.
  • даже если на той же машине путь к файлу может не иметь смысла в контексте IPython.
  • даже если это имеет смысл, протокол Jupyter не предназначен для этого. И у нас нет планов менять эту абстракцию ни в краткосрочной, ни в долгосрочной перспективе.

Тем не менее, вы _можете_ запустить блокнот без сервера блокнота с помощью внешнего скрипта и одновременно скопировать блокнот. Это простая манера jupyter nbconvert --execute --output-dir='results/'

Надеюсь, это поможет.

Может быть, тот факт, что вы закрыли эту тему, сразу говорит о том, что эта тема где-то подробно обсуждалась. Не могли бы вы дать мне ссылку на обсуждение, чтобы я мог лучше понять это решение?

В противном случае мне интересно: почему среда iPython не может установить переменную python, например, внутри модуля IPython, как только запустится ядро? Затем эта переменная может содержать информацию о том, как запустилось ядро, например URL-адрес блокнота iPython.

Нет конкретного места, где это подробно обсуждается, это есть во многих местах, но я воспользуюсь другой метафорой, которую видел раньше.

Вы писатель книг. Ваш читатель регулярно хочет чего-то одного. Поскольку они идентифицируют себя с персонажами, они хотят, чтобы у главного героя был тот же цвет глаз, что и у них. Как ты это делаешь ? Ну, как писатель вы не можете. Для каждого человека ответ очевиден, а для большинства пользователей нет.

Вы можете распечатать 10 версий с 10 цветами глаз и попросить читателя сделать выбор. Но читатель должен это сделать.

То же самое для ядра IPython.

Ядро не знает, что его запустило. То, что началось, может _попробовать_ установить переменную env, но в данном контексте это может даже не иметь смысла. Возможно, у вас не подключен ноутбук. Процесс, который вы запускаете, может быть не python.

У вас есть вещь (ваше ядро), единственной целью которой является выполнение кода. Он может иметь или не иметь доступ к файловой системе, это может быть или не быть python. Он может быть, а может и не быть уже подключен к внешнему интерфейсу. он может или не может быть подключен к нескольким клиентам в течение своей жизни, может быть, даже одновременно.

Таким образом, хотя в каждом случае вы _можете_ дать окончательный ответ о том, есть ли документ, прикрепленный к ядру, и что это такое, общий ответ и как его получить неясны. Вопрос не имеет смысла, по крайней мере, мы его не нашли.

Итак, как читатель книг, вы должны сделать выбор и сообщить ядру имя файла, которое, по вашему мнению, является правильным.

Когда сервер ноутбука запускается, он устанавливает имя связанного с ним файла. Для этого есть технические проблемы, в основном связанные с соединением компонентов, но мы предполагаем, что можем. Пара вопросов из головы.

Какое имя вы устанавливаете при запуске ноутбука через nbconvert?

  • если ввод стандартный?
  • если вход сетевой
  • если выходной блокнот =! input_notebook
  • в режиме «книга», который принимает на вход несколько ноутбуков.
    При подключении консоли какое имя вы указываете?
    Если вы прикрепите несколько блокнотов, какое имя вы установите?

    • Если вы запускаете несколько блокнотов подряд, какое имя вы устанавливаете?

    • Если вы запускаете несколько ноутбуков параллельно, какое имя вы устанавливаете?

      при работе в среде без файловой системы (база данных postgres), какое имя?

      Двоичный или ASCII? Определенная кодировка?

      Имя записной книжки FullPath ?

      А если не на одной машине?

      Что, если выполнение выполняется исключительно в памяти, поскольку записная книжка создается на лету?

      Даже если у вас есть имя и оно print() ... что, если файл будет переименован?

  • переименован при выключенном ядре?
  • переименован во время выполнения ядра?
    Совместная работа в реальном времени и жесткие ссылки, когда файл может иметь несколько имен, какое из них правильное?

Ни один из вышеперечисленных вопросов не имеет для меня четких ответов. Если будет консенсус, как это сделать правильно, не загоняя нас в угол, мы подумаем, и тогда будут все технические сложности.

Надеюсь, это немного прояснит ситуацию. Вы можете попробовать подобные хакерские вещи , но вы увидите, что они редко устраивают всех.

Простите, но с этим:

!echo %cd% # under windows
!pwd # under linux/mac

вы получаете нужную информацию.
Чтобы повторно использовать его, просто выполните:

myInfo01 = !echo %cd% # under windows
myInfo02 = !pwd # under linux/mac

Это не сработает, потому что процесс CWD может измениться и может даже не быть там, где хранится блокнот.

Гарантируется ли, по крайней мере, что если вы откроете блокнот на свежем сервере ноутбуков и неявно запустите ядро, запустив некоторый код, оно получит pwd для папки, в которой находится ipynb-файл?

Тот факт, что ipython не может волшебным образом обрабатывать каждый странный пограничный случай, чего, я думаю, никто не ожидал, не должен мешать ему иметь _простое_ правило, подобное этому, для _простых_ случаев, которые действительно важны для людей (например, передача блокнота + файлы данных в одном и том же месте). папка ученикам)

Гарантируется ли, по крайней мере, что если вы откроете блокнот на свежем сервере ноутбуков и неявно запустите ядро, запустив некоторый код, оно получит pwd для папки, в которой находится ipynb-файл?

Нет.

Не гарантируется, что ядро ​​находится на той же машине, что и ipynb, даже не гарантируется, что файл ipynb вообще существует, будет существовать, уникален или иметь уникальный путь, или даже является/будет файлом. Пример: совместная работа в режиме реального времени на Google Диске.

Думаю, я недостаточно хорошо сформулировал свой вопрос. 200 студентов настроят среду Python, большинство из которых установит Anaconda на свои ноутбуки. Я передам им компьютерное упражнение в виде записной книжки и файлы данных в папке. Один из них может хранить записную книжку в БД postgres, двое могут запускать ядро ​​​​на другом компьютере, отличном от их ноутбука, на котором у них есть записная книжка. Три студента вместе настроят совместную работу в режиме реального времени на Google Диске. Шестеро студентов сделают что-то еще, о чем вы могли или не могли упомянуть до сих пор. В основном я думаю о 190 студентах, которые будут разумно следовать инструкциям, распаковать папку на своем ноутбуке (Windows, OS X или Linux), запустить сервер ноутбука на _тот же_ ноутбуке (либо с помощью обозревателя сервера ноутбука, либо двойной щелчок по файлу ноутбука) и позволить ему неявно запустить новое ядро ​​(опять же на том же ноутбуке), выполнив первую ячейку. Вопрос в том, работает ли cwd для _тех_ студентов. Придут ли ~15 студентов ко мне в офис из-за того, что os.getcwd() не работали, или мне следует ожидать ближе к 50-100?

В основном я думаю о 190 студентах, которые будут разумно следовать инструкциям, разархивировать папку на своем ноутбуке (Windows, OS X или Linux), запустить сервер ноутбука на том же ноутбуке (либо с помощью обозревателя сервера ноутбука, либо двойной щелчок по файлу ноутбука) и позволить ему неявно запустить новое ядро ​​(опять же на том же ноутбуке), выполнив первую ячейку.

Да, для этих пользователей будет работать использование os.cwd() или даже c = !cwd ; и я думаю, что в вашем контексте можно попросить их сделать это. Но как _общий_ вариант использования это не так. мы также постараемся быть осторожными при указании вещей в этом трекере ошибок, поскольку это может быть воспринято как явное одобрение этого метода. И мы знаем, что люди не читают подробно.

Достаточно справедливо, спасибо за вашу заботу о точном общении.

При первом запуске сценария в рабочей книге и до его изменения os.cwd() — это каталог записной книжки.
Так что я часто использую в своем коде

if not 'workbookDir' in globals():
    workbookDir = os.getcwd()
print('workbookDir: ' + workbookDir)
os.chdir(workbookDir)  # If you changed the current working dir, this will take you back to the workbook dir.

Как кажется, большинство пользователей здесь на самом деле не хотят получать доступ к «пути к блокноту», что бы это ни означало в конкретном развертывании, а скорее к ресурсам, связанным с этим блокнотом, таким образом, чтобы детали развертывания абстрагируются.

Очевидно, что распространение блокнотов вместе с соответствующими данными является общим и широким вариантом использования. Может быть, нужен абстрактный механизм для доступа к ресурсам из ядра? Тогда ответственность за развертывание (т.е. установку сервера ноутбука) лежит на правильной настройке этого API доступа к ресурсам, возможно, с помощью некоторых метаданных из ноутбука? Затем локальный сервер записной книжки может по умолчанию фактически обслуживать эти ресурсы по пути, относящемуся к записной книжке. Другие развертывания могут предоставлять отдельный интерфейс (например, метод загрузки или URL-адрес, указывающий на ресурсы) или просто не поддерживать интерфейс вообще.

Сейчас может быть слишком поздно, но похоже, что Colaboratory может помочь вам здесь:
https://colab.research.google.com/notebooks/welcome.ipynb

При запуске блокнота в глобальные переменные вставляется переменная с именем «_dh». Похоже, это каталог записной книжки, хотя я не искал никакой документации по этому вопросу. Тем не менее, это работает для меня прямо сейчас.

Подобно решению @SurealCereal :

if not 'workbookDir' in globals():
    workbookDir = os.getcwd()

Я использовал это сразу после импорта:

try: ipynb_path
except NameError: ipynb_path = os.getcwd()

Что-то в слове «ошибка» заставляет меня дважды подумать, прежде чем возиться с его позицией или существованием.

В качестве альтернативы:

if 'workbookDir' not in globals():

немного читабельнее.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги