__file__ не существует в Jupyter Notebook

Я на сервере Jupyter Notebook (v4.2.2) с Python 3.4.2 и Я хочу использовать глобальное имя __file__, потому что ноутбук будет клонирован от других пользователей и в одном разделе, который я должен запустить:

def __init__(self, trainingSamplesFolder='samples', maskFolder='masks'):
    self.trainingSamplesFolder = self.__getAbsPath(trainingSamplesFolder)
    self.maskFolder = self.__getAbsPath(maskFolder)

def __getAbsPath(self, path):
    if os.path.isabs(path):
        return path
    else:
        return os.path.join(os.path.dirname(__file__), path)

__getAbsPath(self, path) проверяет, является ли параметр path относительным или абсолютным путем и возвращает абсолютную версию path. Поэтому я могу использовать возвращенный path безопасно позже.

Но я получаю ошибку

NameError: name '__file__' не определен

Я искал эту ошибку в Интернете и нашел "решение", которое лучше использовать sys.argv[0], но print(sys.argv[0]) возвращает

/usr/local/lib/python3.4/dist-packages/ipykernel/__main__.py

Но правильное расположение ноутбука должно быть /home/ubuntu/notebooks/.

Спасибо за ссылку Как получить текущее имя IPython Notebook от Martijn Pieters (комментарии), последний ответ (не принят) подходит для моих потребностей:

print(os.getcwd())

/дома/Ubuntu/ноутбуки

Ответы

Ответ 1

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

os.path.abspath('')

преимущества

  • Работает от Jupyter Notebook
  • Это работает из REPL
  • Не требует Python 3.4 pathlib

Обратите внимание, что один сценарий, в котором __file__ имеет преимущество, - это когда вы вызываете python из каталога A, но запускаете сценарий в каталоге B. В этом случае выше, как и в большинстве других методов, будет возвращаться A, а не B. Однако для книги Jupyter вы всегда получаете папка для файла .ipyn вместо каталога, из которого вы запустили jupyter notebook.

Ответ 2

Это не возможно, чтобы получить путь к ноутбуку. Вы можете найти способ получить его, который работает только в одной среде (например, os.getcwd()), но он не обязательно будет работать, если ноутбук загружается другим способом.

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

Смотрите также: https://github.com/ipython/ipython/issues/10123

Ответ 3

В современном Python (v3. 4+) мы можем использовать pathlib для получения каталога ноутбука:

from pathlib import Path

cwd = Path().resolve()
# cwd == PosixPath('/path/to/this/jupyter/ipynb/file's/directory/')

# or this way, thanks @NunoAndré:
cwd = Path.cwd()
# cwd == PosixPath('/path/to/this/jupyter/ipynb/file's/directory/')



Обновить

@ShitalShah Я не могу воспроизвести ошибку, о которой вы сообщаете. Блокнот Jupyter работает нормально, независимо от текущего рабочего каталога, в котором было запущено приложение.

Пример: файл ~/dir1/dir2/untitled.ipynb и блокнот Jupyter запущены в ~/dir1:

Jupyter notebook started in ~/dir1

Записная книжка Jupyter началась в ~/dir1/dir2:

Jupyter notebook started in ~/dir1/dir2

Ответ 4

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

В глобальных переменных есть следы, если вы globals() вы увидите, что есть элемент с ключом _dh, который может вам помочь. Вот как мне удалось загрузить файл data.csv который находится в той же папке, что и моя записная книжка:

import os

current_folder = globals()['_dh'][0]

# Calculating path to the input data
data_location = os.path.join(current_folder,'data.csv')