__file__在Jupyter Notebook中不存在

Fab*_*ian 52 path python-3.x jupyter

我在使用Python 3.4.2 的Jupyter Notebook服务器(v4.2.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)
Run Code Online (Sandbox Code Playgroud)

__getAbsPath(self, path)检查是否一个path参数是相对或绝对路径和返回的绝对版本path.所以我可以path稍后安全地使用.

但是我得到了错误

NameError:'__file__'未定义名称

我在网上搜索了这个错误并找到了我应该更好地使用的"解决方案" sys.argv[0],但是print(sys.argv[0])返回了

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

但正确的笔记本位置应该是/home/ubuntu/notebooks/.

感谢您的参考如何从Martijn Pieters 获取当前的IPython Notebook名称(评论),最后的答案(不接受)非常适合我的需求:

print(os.getcwd())

/家庭/ Ubuntu的电脑/笔记本电脑

Shi*_*hah 33

如果你想获得运行脚本的目录的路径,我强烈推荐使用,

os.path.abspath('')
Run Code Online (Sandbox Code Playgroud)

好处

  • 它适用于Jupyter Notebook
  • 它来自REPL
  • 它不需要Python 3.4的pathlib

请注意,有一个__file__优势的场景是从目录A调用python但在目录B中运行脚本.在这种情况下,上面以及大多数其他方法将返回A,而不是B.但是对于Jupyter notbook,你总是得到文件夹用于.ipyn文件而不是您启动的目录jupyter notebook.

  • @Shital,不整齐的头发是正确的。这与下面 mab 的其他建议一样,不起作用。它只是给你cwd。 (5认同)
  • 这对我不起作用。当我用纸厂运行笔记本时,它给了我“工作目录”。 (2认同)

mic*_*ael 14

无法获得笔记本电脑的路径.您可能会找到一种方法来获取它只能在一个环境中工作(例如os.getcwd()),但如果笔记本以不同的方式加载,它将不一定有效.

相反,尝试编写笔记本,以便它不需要知道自己的路径.如果做了类似于获取pwd的事情,那么一定要快速失败/打印错误,如果这不起作用,而不是默默地继续尝试.

另见:https://github.com/ipython/ipython/issues/10123

  • 你是对的,不可能使用 os.getcwd() 获取笔记本的路径。这仅仅获得了cwd。如果您在笔记本中更改了该内容,则返回到该单元格,您将不会获得笔记本目录。这是一个大问题。不,我不同意您编写脚本时不需要知道它在哪里。这样做有很好的理由,例如复制到另一个位置。 (2认同)

mab*_*mab 14

在现代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/')
Run Code Online (Sandbox Code Playgroud)



更新

@ShitalShah我无法重现您报告的错误.Jupyter笔记本似乎工作正常,无论应用程序启动当前的工作目录.

示例:文件~/dir1/dir2/untitled.ipynb和Jupyter笔记本开始于~/dir1:

Jupyter笔记本开始于〜/ dir1

Jupyter笔记本开始于~/dir1/dir2:

Jupyter笔记本以〜/ dir1/dir2开头

  • @mac,这不起作用。如果您更改笔记本中的 cwd,然后重新执行该单元,它将为您提供新的 cwd,而不是笔记本的位置。这是 Jupyter Notebook 中严重缺失的功能。我不得不求助于涉及 Javascript 的 hack。真是个皮塔饼啊。 (4认同)
  • `Path` 有一个类方法:`Path.cwd()` (2认同)
  • @mab:尝试“import os;os.chdir('path/to/new/dir')”。如果您现在尝试“Path.cwd()”和“Path().resolve()”,它们都指向“path/to/new/dir”,而不是笔记本的位置! (2认同)

shy*_*kov 10

__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')
Run Code Online (Sandbox Code Playgroud)

  • 哇,恭喜@shytikov,您的方法“确实有效”,应该是首选方法。您已经找到了避免难看的JS骇客的方法。非常感谢。现在,如果我们可以获取笔记本名称的话... (2认同)
  • 当使用 papermill 从不同的目录执行笔记本时,这对我不起作用。`os.getcwd()` 和 `globals()["_dh"]` 都显示了我运行 papermill 命令的目录,而不是笔记本模板的目录或执行的笔记本将登陆的目录 (2认同)