jupyter notebook 获取文件名字
前言:
普通的 python
文件中可以通过 file 获取到当前文件名称,但是在 jupyter notebook
中却难以获取。
通过参数的:
import sys, os
sys.argv [0]
out:
'[路径]/lib/python3.6/site-packages/ipykernel_launcher.py'
获取方法
通过 JS 方法
- 有以下与IPython 2.0一起使用的东西。观察到笔记本的名称作为属性的值存储在页面
'data-notebook-name'
的<body>
标签中。因此,首先想到的是让Javascript检索属性-借助魔术,可以从代码单元中调用JavaScript%%javascript
。然后,可以通过设置Python变量的命令通过调用Python内核来访问Javascript变量。由于从内核知道了最后一个变量,因此也可以在其他单元中对其进行访问。
%%javascript
var kernel = IPython.notebook.kernel;
var body = document.body,
attribs = body.attributes;
var command = "theNotebook = " + "'"+attribs['data-notebook-name'].value+"'";
kernel.execute(command);
print(theNotebook)
out:
docu_name
该解决方案的一个缺陷是,当一个人更改笔记本的标题(名称)时,该名称似乎不会立即更新(可能存在某种缓存),因此有必要重新加载笔记本以访问该笔记本的新名字。
- 通过获取页面 id 标签的方法获取,实时更新。
%%javascript
var kernel = IPython.notebook.kernel;
var thename = window.document.getElementById("notebook_name").innerHTML;
var command = "theNotebook = " + "'"+thename+"'";
kernel.execute(command);
print(theNotebook)
out:
docu_name
与第 1 种解决方案相反,笔记本名称的修改会立即更新,因此无需刷新笔记本。
- 在Jupyter 3.0上,以下工作。在这里,我显示了Jupyter服务器上的整个路径,而不仅仅是笔记本名称:
%%javascript
var nb = IPython.notebook;
var kernel = IPython.notebook.kernel;
var command = "NOTEBOOK_FULL_PATH = '" + nb.base_url + nb.notebook_path + "'";
kernel.execute(command);
print("NOTEBOOK_FULL_PATH:\n", NOTEBOOK_FULL_PATH)
out:
NOTEBOOK_FULL_PATH:
path/docu_name.ipynb
- 更简洁的方式
%%javascript
IPython.notebook.kernel.execute('nb_name = "' + IPython.notebook.notebook_name + '"')
import os
nb_full_path = os.path.join(os.getcwd(), nb_name)
nb_full_path
out:
'[path]/docu_name.ipynb'
- 通过
ipyparams
的方式
import ipyparams
currentNotebook = ipyparams.notebook_name
缺点:有时候需要执行两次才能获取到
- 又是
javascript
from IPython.display import display, Javascript
# can have comments here :)
js_cmd = 'IPython.notebook.kernel.execute(\'nb_name = "\' + IPython.notebook.notebook_name + \'"\')'
display(Javascript(js_cmd))
- 通过
session
的方式
异步js并不总是一个很好的解决方案。例如我试图使用它来获取日志记录的nb名称,但是它不适用于自动化, run all
的时候会出现 not define
的问题,因此幸运的是其他人找到了非js脚本解决方案(有一些小限制):
首先在 ~/.jupyter/jupyter_notebook_config.py
文件中设置 token
#c.NotebookApp.token = '<generated>'
取消注释并设置 token
的值。
from notebook import notebookapp
import urllib, json, os, ipykernel, ntpath
def ipy_nb_name():
""" Returns the short name of the notebook w/o .ipynb
or get a FileNotFoundError exception if it cannot be determined
NOTE: works only when the security is token-based or there is also no password
"""
connection_file = os.path.basename(ipykernel.get_connection_file())
kernel_id = connection_file.split('-', 1)[1].split('.')[0]
for srv in notebookapp.list_running_servers():
try:
if srv['token']=='' and not srv['password']: # No token and no password, ahem...
req = urllib.request.urlopen(srv['url']+'api/sessions')
else:
req = urllib.request.urlopen(srv['url']+'api/sessions?token='+srv['token'])
sessions = json.load(req)
for sess in sessions:
if sess['kernel']['id'] == kernel_id:
nb_path = sess['notebook']['path']
return ntpath.basename(nb_path).replace('.ipynb', '') # handles any OS
except:
pass # There may be stale entries in the runtime directory
raise FileNotFoundError("Can't identify the notebook name")
ipy_nb_name()