Aus*_*art 5 python jupyter-notebook
我有一个 Jupyter Notebook 正在运行。我希望能够从 Python 中访问当前 Jupyter Notebook 的源代码。我的最终目标是将其传入,ast.parse以便我可以对用户的代码进行一些分析。理想情况下,我可以做这样的事情:
import ast
ast.parse(get_notebooks_code())
Run Code Online (Sandbox Code Playgroud)
显然,如果源代码是 IPYNB 文件,则需要从 Python 单元中提取代码的中间步骤,但这是一个相对容易解决的问题。
到目前为止,我已经找到了将使用list_running_serversIPython 对象的函数来发出请求并匹配内核 ID 的代码 - 这为我提供了当前正在运行的笔记本的文件名。这会起作用,但磁盘上的源代码可能与用户在浏览器中的内容不匹配(直到您保存新的检查点)。
我已经看到一些涉及使用 JavaScript 提取数据的想法,但这需要一个带有魔法的单独单元格或调用 display.Javascript 函数 - 异步触发,因此不允许我将结果传递给ast.parse.
对于如何在 Python 中以字符串形式动态获取当前笔记本源代码以供立即处理,任何人都有任何聪明的想法?如果我需要使它成为扩展甚至内核包装器,我完全没问题,我只需要以某种方式获取源代码。
嗯,这不是我想要的,但这是我目前的策略。我需要根据用户的代码运行一些 Python 代码,但它实际上不必直接连接到用户的代码。所以我将在之后运行以下魔法:
%%javascript
// Get source code from cells
var source_code = Jupyter.notebook.get_cells().map(function(cell) {
if (cell.cell_type == "code") {
var source = cell.code_mirror.getValue();
if (!source.startsWith("%%javascript")) {
return source;
}
}
}).join("\n");
// Embed the code as a Python string literal.
source_code = JSON.stringify(source_code);
var instructor_code = "student_code="+source_code;
instructor_code += "\nimport ast\nprint(ast.dump(ast.parse(student_code)))\nprint('Great')"
// Run the Python code along with additional code I wanted.
var kernel = IPython.notebook.kernel;
var t = kernel.execute(instructor_code, { 'iopub' : {'output' : function(x) {
if (x.msg_type == "error") {
console.error(x.content);
element.text(x.content.ename+": "+x.content.evalue+"\n"+x.content.traceback.join("\n"))
} else {
element.html(x.content.text.replace(/\n/g, "<br>"));
console.log(x);
}
}}});
Run Code Online (Sandbox Code Playgroud)