我有一个 jupyter/ipython
笔记本,用于原型(prototype)设计和辅导。
我使用菜单下拉菜单或 nbconvert
将其导出为 python 脚本,即
ipython nbconvert --to python notebook.ipynb
但是,我想让
notebook.py
直接可执行,而不必每次都手动修改它,以便我可以不断更新 notebook.ipynb
并用我的更改覆盖 notebook.py
。我还想在 notebook.py
中包含命令行参数。例如,我的样板是:#!/usr/bin/env ipython
import sys
x=sys.argv[-1]
当然使用
chmod +x notebook.py
。一种方法可能是在
jupyter/ipython
笔记本中使这些行(无论是 python 还是命令行指令)可忽略 - 有没有办法做到这一点,例如检测 jupyter/ipython
环境?Edit1: 这相当于说:
如何在
notebook.ipynb
中包含在 notebook 环境中将被忽略但在从中生成的 notebook.py
中解析的行?Edit2: 这个问题是部分答案,但没有告诉我如何包含
#!/usr/bin/env ipython
行:How can I check if code is executed in the IPython notebook?Edit3: 可能有用,但前提是
%%bash /usr/bin/env ipython
可以工作 - 它会..吗? How do I provide inline input to an IPython (notebook) shell command?Edit4: 另一个尝试的答案(微妙):由于
#
是 python 中的注释,将 #!/usr/bin/env ipython
放在笔记本的第一个单元格中意味着它将在 jupyter/ipython
中被忽略,但在导出的 notebook.py
中受到尊重。但是, #!
指令不在顶部,但很容易被砍掉:> more notebook.py
# coding: utf-8
# In[1]:
#!/usr/bin/env ipython
# In[2]:
print 'Hello'
# In[ ]:
最佳答案
结果证明答案相当简单。
第 1 部分 - 使导出的 notebook.py 直接可执行:
如 here 所述,nbconvert
可以使用任意模板进行自定义。
所以创建一个文件 hashbang.tpl
包含:
#!/usr/bin/env ipython
{% extends 'python.tpl'%}
然后在命令行执行:
jupyter nbconvert --to python 'notebook.ipynb' --stdout --template=hashbang.tpl > notebook.py
嗨,快点:
> more notebook.py
#!/usr/bin/env ipython
# coding: utf-8
# In[1]:
print 'Hello'
...
第 2 部分 - 检测笔记本环境:
https://stackoverflow.com/a/39662359/1021819 的这个答案应该可以做到,即使用以下函数来测试笔记本环境:
def isnotebook():
# From https://stackoverflow.com/a/39662359/1021819
try:
shell = get_ipython().__class__.__name__
if shell == 'ZMQInteractiveShell':
return True # Jupyter notebook or qtconsole
elif shell == 'TerminalInteractiveShell':
return False # Terminal running IPython
else:
return False # Other type (?)
except NameError:
return False # Probably standard Python interpreter
关于python - 将 ipython notebook 转换为可直接执行的 python 脚本,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45605033/