假设您询问的是交互性,您可以尝试一下。
如果您想知道 Jupyter 如何知道单元格的输出何时结束:好吧,它显然不知道,它只是将任何捕获的输出转储到最近活动的单元格中:
import threading,time
a=5
threading.Thread(target=lambda:[print(a),time.sleep(20),print(a)]).start()
(故意比漂亮的例子短,因为这只是侧面信息。在 20 秒的等待运行期间,您有时间激活另一个单元格,可能通过发出 a=6)
这可以用来将一些控制台代码的输出到屏幕上,同时从主线程控制它:
import sys,threading,subprocess
proc=subprocess.Popen('/bin/sh',stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.STDOUT)
pout=proc.stdout
pin=proc.stdin
def outLoop():
running=True
while(running):
line=pout.readline().decode(sys.stdout.encoding)
print(line,end='')
running='\n' in line
print('Finished')
threading.Thread(target=outLoop).start()
然后你可以发出命令,比如
pin.write(b'ls -l\n')
pin.flush()
和
pin.write(b'exit\n')
pin.flush()
即使b'ls\nexit\n' 有效,这就是outLoop 如此长的原因(一个简单的while(proc.poll() is None)-print(...) 循环会在它获取所有输出之前完成。
然后整个事情可以自动化为:
while(proc.poll() is None):
inp=bytearray(input('something: ')+'\n',sys.stdin.encoding)
if(proc.poll() is None):
pin.write(inp)
pin.flush()
这在https://try.jupyter.org/ 上运行良好,但显然我不想尝试在那里安装 conda 包,所以我不知道当 conda 提出问题时会发生什么。
幸运的是,输入字段位于单元格底部(使用ls;sleep 10;ls 测试)。不幸的是,输入字段最后需要一个额外的条目才能消失(这已经是“很好”的方式,当它是一个简单的 while(...)-write(bytearray(input()))-flush() 3-liner 时,它是异常退出。
如果有人想在 Windows 上尝试这个,它适用于 'cmd',但我建议使用硬编码的 'windows-1252' 而不是 sys.stdin/out.encoding:他们说 UTF-8,但一个简单的 dir 命令已经产生了输出它既不是 UTF-8 也不是 ASCII(大小为 3 位组之间的不可破坏空格是 0xA0 字符)。或者只是删除decode 部分(并使用running=0xA in line)