我试图运行IPython的笔记本电脑时获得当前笔记本的名称。 我知道我可以在笔记本电脑的顶部看到它。 我所喜欢的东西后,
currentNotebook = IPython.foo.bar.notebookname()
我需要在一个变量获得的名称。
我试图运行IPython的笔记本电脑时获得当前笔记本的名称。 我知道我可以在笔记本电脑的顶部看到它。 我所喜欢的东西后,
currentNotebook = IPython.foo.bar.notebookname()
我需要在一个变量获得的名称。
前面已经提到,你可能是不是真的应该是能够做到这一点,但我没有找到一个方法。 这是一个燃烧的黑客,所以,不要依赖这种不惜一切:
import json
import os
import urllib2
import IPython
from IPython.lib import kernel
connection_file_path = kernel.get_connection_file()
connection_file = os.path.basename(connection_file_path)
kernel_id = connection_file.split('-', 1)[1].split('.')[0]
# Updated answer with semi-solutions for both IPython 2.x and IPython < 2.x
if IPython.version_info[0] < 2:
## Not sure if it's even possible to get the port for the
## notebook app; so just using the default...
notebooks = json.load(urllib2.urlopen('http://127.0.0.1:8888/notebooks'))
for nb in notebooks:
if nb['kernel_id'] == kernel_id:
print nb['name']
break
else:
sessions = json.load(urllib2.urlopen('http://127.0.0.1:8888/api/sessions'))
for sess in sessions:
if sess['kernel']['id'] == kernel_id:
print sess['notebook']['name']
break
我更新了我的答案,包括“工作”的IPython 2.0至少有一个简单的测试解决方案。 它可能不能保证给出正确的答案,如果有连接到同一个内核的多个笔记本电脑等
我有与IPython的2.0工作的下面。 我观察到笔记本电脑的名称存储为属性的值'data-notebook-name'
在<body>
页面的标签。 这样的想法是先问Javascript来检索属性--javascripts可以从codecell由于被调用到%%javascript
魔力。 则有可能通过对内核的Python的呼叫来访问JavaScript变量,利用该设置一个Python变量的命令。 由于这最后一个变量从内核已知的,它可以在其他单元格进行访问也是如此。
%%javascript
var kernel = IPython.notebook.kernel;
var body = document.body,
attribs = body.attributes;
var command = "theNotebook = " + "'"+attribs['data-notebook-name'].value+"'";
kernel.execute(command);
从Python代码单元
print(theNotebook)
出[]:HowToGetTheNameOfTheNoteBook.ipynb
在这个解决方案的缺点是,当一个人改变笔记本的标题(名称),那么这个名字似乎不会立即更新(有可能是某种缓存),它是需要重新装笔记本电脑获得访问新名字。
[编辑]在反射,更高效的解决方案是寻找输入字段用于笔记本的名称,而不是<body>
标记。 展望源,看来这个领域具有ID“NOTEBOOK_NAME”。 然后,可以通过捕获这个值document.getElementById()
然后按照相同的方法如上。 代码变得,仍然使用JavaScript魔术
%%javascript
var kernel = IPython.notebook.kernel;
var thename = window.document.getElementById("notebook_name").innerHTML;
var command = "theNotebook = " + "'"+thename+"'";
kernel.execute(command);
然后,从IPython中的细胞,
In [11]: print(theNotebook)
Out [11]: HowToGetTheNameOfTheNoteBookSolBis
相反,第一个解决方案,笔记本电脑的名称修改会被立即更新,也没有必要刷新笔记本电脑。
在Jupyter 3.0以下工作。 在这里,我展示Jupyter服务器,不只是笔记本电脑的名称在整个路径:
为了存储NOTEBOOK_FULL_PATH
对当前笔记本前端:
%%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)
运行第一个JavaScript细胞不产生输出。 运行的第二个Python细胞产生类似:
NOTEBOOK_FULL_PATH:
/user/zeph/GetNotebookName.ipynb
添加到以前的答案,
让笔记本运行名在单元格中的以下内容:
%%javascript
IPython.notebook.kernel.execute('nb_name = "' + IPython.notebook.notebook_name + '"')
这让你在nb_name文件名
然后让你可以使用一个单独的单元下面的完整路径:
import os
nb_full_path = os.path.join(os.getcwd(), nb_name)
看来我不能评论,所以我必须张贴此作为一个答案。
通过@iguananaut接受的解决方案,并通过@mbdevpl更新似乎不与最新版本的笔记本电脑来工作。 我固定它,如下所示。 我查了一下它的Python v3.6.1 +笔记本V5.0.0和Python的v3.6.5和笔记本V5.5.0。
from notebook import notebookapp
import urllib
import json
import os
import ipykernel
def notebook_path():
"""Returns the absolute path of the Notebook or None 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:
return os.path.join(srv['notebook_dir'],sess['notebook']['path'])
except:
pass # There may be stale entries in the runtime directory
return None
由于在文档字符串表示,这只有当任一没有认证或者认证是基于令牌的。
需要注意的是,由于也被别人报道,基于JavaScript的方法似乎并不执行“运行的所有单元格”时的工作(但在执行单元“手动”时有效),这是一个交易断路器我。