下面是使用 Jupyter Notebook 的 Python 内核从自定义 JavaScript 客户端执行 Python 代码的草案,这是一个相关问题:
Where is a docs for Jupyter front-end extensions JavaScript API?
我的草稿适用于一些示例。但是,我仍然存在一些时间问题。
=>Jupyter内核的execute方法的执行顺序是否有bug?
或者这是预期的行为吗?如果是这样,建议使用执行方法的方式是什么/我应该如何调整我的代码以便我的“JupyterTerminal”可以以通用方式使用?
当使用我的方法executePythonCode
执行以下Python代码时,首先调用回调shell
,解决我的 promise 。我的调用主代码将继续执行。随后,调用 iopub 回调,为我提供所需的文本内容。
file = open("D:/forecast4/trunk/databases/Demo/template.xml", "r")
print(file.read())
但是,我希望首先调用 iopub
,然后调用 shell
。 我希望我的调用代码等待,直到检索到文本。
我尝试删除 shell
部分中的 resolve();
命令,这样我的 Promise 就不会过早得到解决。这适用于上面的文本阅读示例。
但是,当执行没有输出的代码时,Promise 永远不会被解析。因此,我似乎需要在 shell
回调中调用resolve()。
如何使用 Jupyter Notebook 内核从自定义 JavaScript 客户端执行 Python 代码的示例(仍然存在一些计时问题):
export default class JupyterTerminal {
constructor(jupyter){
this.__kernel = jupyter.notebook.kernel;
}
async executePythonCode(pythonCode){
var self=this;
return new Promise(function(resolve, reject) {
var isResolved=false;
var callbacks = {
shell : {
reply : (data)=>{
var content = data.content
switch(content.status){
case 'ok':
isResolved=true;
resolve();
break;
case 'error':
reject(content.evalue)
break;
default:
throw new Error('Not yet implemented content status "' + content.status + '"');
}
},
},
iopub : {
output : (data)=>{
var content = data.content;
switch(content.name){
case 'stderr':
if(isResolved){
var message = 'Could not handle strr output while executing Python code '
+'because Promise already has been resolved:\n' + content.text;
console.error(message);
}
reject(content.text);
break;
case 'stdout':
if(isResolved){
var message = 'Could not handle stout output while executing Python code '
+'because Promise already has been resolved:\n' + content.text;
console.error(message);
}
resolve(content.text);
break;
case undefined:
reject(content.ename + ': ' + content.evalue);
break;
default:
throw new Error('Not yet implemented content type "' + content.name + '"');
}
}
}
};
self.__kernel.execute(pythonCode, callbacks);
});
}
}
最佳答案
这是我能想到的最简单的版本,似乎可行。您必须用您的案例对其进行测试,看看它是否真的更好。关键是要记住,如果没有 print()
包装您的语句,就没有输出。在下面的示例中,如果您仅输入语句 1+1
,则将以“ok”作为状态进行解析。
function wait_for_python(cmdstr){
return new Promise((resolve,reject) => {
var callbacks = {
iopub: {
output: (data) => resolve(data.content.text.trim())
},
shell: {
reply: (data) => resolve(data.content.status)
}
};
Jupyter.notebook.kernel.execute(cmdstr, callbacks);
});
}
wait_for_python('print(1+1)').then((resolve)=>alert(resolve));
关于javascript - 如何在Javascript中正确使用Jupyter笔记本的kernel.execute方法(计时问题)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55828900/