在 ipython 笔记本中读取单元格内容 [英] Read cell content in an ipython notebook
问题描述
我有一个 ipython
笔记本,其中包含混合的 markdown
和 python
单元.
I have an ipython
notebook with mixed markdown
and python
cells.
我希望我的一些 python
单元格读取相邻的 markdown
单元格并将它们作为输入处理.
And I'd like some of my python
cells to read the adjacent markdown
cells and process them as input.
所需情况的示例:
CELL 1 (markdown):要执行的 SQL 代码
CELL 1 (markdown): SQL Code to execute
CELL 2 (markdown):select * from tbl where x=1
CELL 3 (python) : mysql.query(ipython.previous_cell.content)
(语法ipython.previous_cell.content
组成)
执行CELL 3"应该等价于 mysql.query("select * from tbl where x=1")
这怎么办?
推荐答案
我认为您试图以错误的方式解决问题.
I think you are trying to attack the problem the wrong way.
首先是的,有可能以非常黑客的方式获取相邻的 Markdown 单元格,而这在无头笔记本执行中是行不通的.
First yes, it is possible to get the adjacent markdown cell in really hackish way that would not work in headless notebook execution.
您想要做的是使用 IPython 单元格魔术,只要单元格以 2 个百分号开头,后跟一个标识符,它就允许使用任意语法.
What you want to do is use IPython cell magics, that allow arbitrary syntax as long as the cell starts with 2 percent signs followed by an identifier.
通常您需要 SQL 单元格.
Typically you want SQL cells.
您可以参考有关细胞魔法的文档或者我可以向您展示如何构建它:
You can refer to the documentation about cells magics or I can show you how to build that :
from IPython.core.magic import (
Magics, magics_class, cell_magic, line_magic
)
@magics_class
class StoreSQL(Magics):
def __init__(self, shell=None, **kwargs):
super().__init__(shell=shell, **kwargs)
self._store = []
# inject our store in user availlable namespace under __mystore
# name
shell.user_ns['__mystore'] = self._store
@cell_magic
def sql(self, line, cell):
"""store the cell in the store"""
self._store.append(cell)
@line_magic
def showsql(self, line):
"""show all recorded statements"""
print(self._store)
## use ipython load_ext mechanisme here if distributed
get_ipython().register_magics(StoreSQL)
现在您可以在 Python 单元格中使用 SQL 语法:
Now you can use SQL syntax in your python cells:
%%sql
select * from foo Where QUX Bar
第二个单元格:
%%sql
Insert Cheezburger into Can_I_HAZ
检查我们执行的内容(3个破折号显示输入/输出分隔,您不必键入它们):
check what we executed (the 3 dashes show the input /output delimitation, you do not have to type them):
%showsql
---
['select * from foo Where QUX Bar', 'Insert Cheezburger into Can_I_HAZ']
以及您在问题开头提出的问题:
And what you asked at the beginning in your question:
mysql.query(__mystore[-1])
这当然要求您以正确的顺序执行前面的单元格,没有什么可以阻止您使用 %%sql
语法来命名您的单元格,例如如果 _store
是一个 dict
,或者更好的一个类,您可以在其中覆盖 __getattr__
,像 __getitem__
一样使用点语法访问字段.这留给读者作为练习,或者结束看回复:
This of course does require that you execute the previous cells in the right order, nothing prevent you from using the %%sql
syntax to name your cells, e.g if _store
is a dict
, or better a class where you overwrite __getattr__
, to act like __getitem__
to access fields with dot syntax . This is left as an exercise to the reader, or end see of the response:
@cell_magic
def sql(self, line, cell):
"""store the cell in the store"""
self._store[line.strip()] = cell
然后你可以像
%%sql A1
set foo TO Bar where ID=9
然后在你的 Python 单元格中
And then in your Python cells
mysql.execute(__mystore.A1)
我还强烈建议查看 Catherine Develin SqlMagic 以获取 IPython,以及这个 GitHub 上的笔记本要点,实时展示这一切.
I would also strongly suggest looking at Catherine Develin SqlMagic for IPython, and this Notebook gist on GitHub that show this all thing live.
在评论中,您似乎说要添加 pig
,没有什么可以阻止您使用 %%pig
魔法.也可以注入 Javascript 以启用 SQL 和 PIG 的正确语法突出显示,但这超出了本问题的范围.
In the comment you seem to say you want to add pig
, nothing prevent you from having a %%pig
magic neither. It is also possible to inject Javascript to enable correct Syntax Highlighting of SQL and PIG, but that's beyond the scope of this question.
这篇关于在 ipython 笔记本中读取单元格内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!