Ipython: 如何从 IPython 中找出当前 ipynb 文件的路径?

创建于 2017-01-05  ·  15评论  ·  资料来源: ipython/ipython

有没有办法从 iPython 中找出当前的 ipynb 文件?

用例:我想从 IPython 中触发模拟。 为了记录所有内容,我想将 IPython 笔记本复制到结果文件夹中,最好是从 IPython 中复制。

用这个问题在网上搜索表明,似乎对这样的功能很感兴趣,但在 stackoverflow 上提出的解决方案似乎都有点 hacky。 或者这已经实施了吗?

最有用的评论

对不起,但是这样:

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

你得到想要的信息。
为了重新使用它,只需执行以下操作:

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

所有15条评论

这是不可能的,如果没有 hack 是不可能的(显示执行 Python 代码的 Javascript)。

以下是内核(在本例中为 IPython)的一些原因:

  • 可能不是从单个文件运行
  • 即使一个文件,该文件也可能不是笔记本。
  • 即使是笔记本,笔记本也可能不在文件系统上。
  • 即使在文件系统上,它也可能不在同一台机器上。
  • 即使在同一台机器上,文件的路径在 IPython 上下文中也可能没有意义。
  • 即使它有意义,Jupyter 协议也没有被设计成这样做。 而且我们没有短期或长期改变这种抽象的计划。

不过,您_可以_通过外部脚本在没有笔记本服务器的情况下运行笔记本,并同时复制笔记本。 这是jupyter nbconvert --execute --output-dir='results/'的简单方式

希望有帮助。

也许您立即关闭此问题的事实表明,该主题已在其他地方进行了彻底的讨论。 你能给我一个讨论的链接,以便我更好地理解这个决定吗?

否则我想知道:为什么 iPython 环境不能在内核启动后立即在 IPython 模块中设置 python 变量? 然后,此变量可以保存有关内核如何启动的信息,例如 iPython 笔记本的 URL。

没有特别的地方对此进行了彻底的讨论,它在很多地方,但我将重用我以前见过的另一个比喻。

你是一个书作家。 你的读者经常想要一件事。 当他们认同角色时,他们希望主角拥有与他们相同的眼睛颜色。 你是怎样做的 ? 作为一个作家,你不能。 对于每个人来说,答案是显而易见的,但对于大多数用户来说,你不能。

您可以打印 10 个版本,10 种眼睛颜色,请读者选择。 但读者_不得不_去做。

IPython 内核也是如此。

内核不知道是什么启动了它。 开始的事情可以_try_设置一个环境变量,但在这种情况下它甚至可能没有意义。 您可能没有连接笔记本电脑。 你启动的进程可能不是python。

你有一个东西(你的内核),它的唯一目的是执行代码。 它可能有权访问文件系统,也可能没有,它可能是也可能不是 python。 它可能已经或可能尚未连接到前端。 它可能会或可能不会在其生命周期内连接到多个客户端,甚至可能同时连接到多个客户端。

因此,虽然在每种情况下,您都_可能_给出一个明确的答案,即是否有一个文档附加到内核以及它是什么,但一般的响应以及如何获得它还不清楚。 这个问题没有意义,或者至少我们还没有找到。

因此,作为书籍阅读者,您必须做出选择并告诉内核_您_认为正确的文件名。

当笔记本服务器启动时,它会设置链接到它的文件的名称。 这样做存在技术挑战,主要不是耦合组件,但假设我们可以。 从我的头顶几个问题。

通过 nbconvert 运行笔记本时,您设置了什么名称?

  • 如果输入是标准输入?
  • 如果输入是网络
  • 如果输出笔记本=! 输入笔记本
  • 在“bookbook”模式下,输入多个笔记本。
    连接控制台时,您设置了什么名称?
    如果您附加多个笔记本,您设置什么名称?

    • 如果您连续执行多个笔记本,您设置什么名称?

    • 如果您并行执行多个笔记本,您设置什么名称?

      在没有文件系统(postgres DB)的环境中工作时,名称是什么?

      二进制还是ASCII? 定义编码?

      FullPath 的笔记本名称?

      如果不在同一台机器上怎么办?

      如果因为 notebook 是动态生成的,所以纯粹在内存中执行呢?

      即使你有一个名字和print()它......如果文件被重命名了怎么办?

  • 内核关闭时重命名?
  • 在内核执行期间重命名?
    文件可能有多个名称时的实时协作和硬链接,哪个是正确的?

上述问题对我来说都没有明确的答案。 如果在如何正确地做到这一点上达成共识,而不是将我们困在角落里,我们会考虑它,然后就会有所有的技术困难。

希望澄清一下。您可以尝试这样的骇人听闻的事情,但您会发现它们很少满足所有人。

对不起,但是这样:

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

你得到想要的信息。
为了重新使用它,只需执行以下操作:

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

它不会起作用,因为进程 CWD 可能会改变,甚至可能不是笔记本的存储位置。

是否至少可以保证,如果您在新的笔记本服务器中打开笔记本并通过运行一些代码隐式启动内核,它将获得 ipynb 文件所在的文件夹的 pwd 吗?

仅仅因为 ipython 不能神奇地处理每一个奇怪的边缘情况,我认为没有人预料到,不应该阻止它有一个像人们真正关心的 _simple_ 情况一样的 _simple_ 规则(比如同时处理笔记本 + 数据文件)文件夹给学生)

是否至少可以保证,如果您在新的笔记本服务器中打开笔记本并通过运行一些代码隐式启动内核,它将获得 ipynb 文件所在的文件夹的 pwd 吗?

不。

不保证内核与 ipynb 在同一台机器上,甚至不保证 ipynb 文件是否存在、将存在、唯一或具有唯一路径,甚至是/将是一个文件。 示例:Google Drive 上的实时协作。

我认为我没有很好地提出我的问题。 200 名学生将有一个 python 环境设置,大多数通过在他们自己的笔记本电脑上安装 anaconda。 我会将计算机练习作为笔记本和文件夹中的数据文件交给他们。 其中一个可能将笔记本存储在 postgres DB 中,两个可能在与他们拥有笔记本的笔记本电脑不同的机器上运行内核。 三名学生将一起在 google drive 上设置实时协作。 六名学生会做一些你到目前为止可能或可能没有提到的事情。 我主要考虑 190 名学生将合理遵循说明,在他们自己的笔记本电脑(Windows、OS X 或 Linux)上解压缩文件夹,在_same_笔记本电脑上启动笔记本服务器(通过笔记本服务器资源管理器或双击笔记本文件),并让它通过执行第一个单元隐式启动一个新内核(再次在同一台笔记本电脑上)。 问题是 cwd 是否适用于_那些_学生。 大约 15 名学生会因为os.getcwd()没有工作而来到我的办公室,还是我应该期望接近 50-100?

我主要考虑 190 名学生将合理遵循说明,在他们自己的笔记本电脑(Windows、OS X 或 Linux)上解压缩文件夹,在同一台笔记本电脑上启动笔记本服务器(通过笔记本服务器资源管理器或双击笔记本文件),并让它通过执行第一个单元隐式启动一个新内核(再次在同一台笔记本电脑上)。

是的,使用 os.cwd() 甚至c = !cwd将适用于这些用户; 我认为在你的情况下,要求他们这样做是很好的。 但作为一个_general_用例,情况并非如此。 我们还会在此错误跟踪器上声明内容时尽量小心,因为它可能会作为对该方法的明确认可而传递。 我们知道人们不会深入阅读。

很公平,感谢您对精确沟通的关注。

一次在工作簿中运行脚本时,在更改之前, 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 等级

相关问题

ghost picture ghost  ·  4评论

frenzymadness picture frenzymadness  ·  3评论

ericdill picture ericdill  ·  3评论

quchunguang picture quchunguang  ·  3评论

henryiii picture henryiii  ·  3评论