将 exec() 输出发送到另一个流而不重定向标准输出
Send `exec()` output to another stream without redirecting stdout
我正在编写一个 Sublime Text 插件,它提供多个 Python shell 可通过 UNIX 套接字访问。每个 shell 都应该在其自己的线程上充当独立的 REPL 运行。 (这些 shell 拥有自己的进程是不可取的;共享一个进程是绝对必要的。)
如果代码是用 mode='single'
编译的,那么内置 exec()
函数会将输出打印到标准输出,并且是一个不计算为 None 的表达式。我需要通过套接字发送此输出。
我知道 patching stdout 可以做到这一点。但是,这在这里不起作用,因为多个控制台可能 运行 在多个线程中(加上内置控制台)。
我的思路如下:
- 尝试
compile()
输入mode='eval'
,eval()
它,并打印结果(如果不是None)。如果无法编译,请尝试 mode='exec'
而不是 mode='single'
.
- 对于每个控制台的线程,将输出流保存在线程本地存储中。在调用 "regular" stdout.
之前,用一个检查这些流的对象修补 sys.stdout
- 以某种方式为每个控制台提供补丁
sys
。
这些似乎不是什么好主意。还有更好的吗?
如果您对单一进程死心塌地,那么根据您是否愿意深入研究 CPython 实现的晦涩的 C 级特性,您可以尝试研究 subinterpreters。据我所知,这些是 CPython 在单个进程中提供的最高级别的隔离,它们允许为单独的子解释器提供单独的 sys.stdout
对象。
我正在编写一个 Sublime Text 插件,它提供多个 Python shell 可通过 UNIX 套接字访问。每个 shell 都应该在其自己的线程上充当独立的 REPL 运行。 (这些 shell 拥有自己的进程是不可取的;共享一个进程是绝对必要的。)
如果代码是用 mode='single'
编译的,那么内置 exec()
函数会将输出打印到标准输出,并且是一个不计算为 None 的表达式。我需要通过套接字发送此输出。
我知道 patching stdout 可以做到这一点。但是,这在这里不起作用,因为多个控制台可能 运行 在多个线程中(加上内置控制台)。
我的思路如下:
- 尝试
compile()
输入mode='eval'
,eval()
它,并打印结果(如果不是None)。如果无法编译,请尝试mode='exec'
而不是mode='single'
. - 对于每个控制台的线程,将输出流保存在线程本地存储中。在调用 "regular" stdout. 之前,用一个检查这些流的对象修补
- 以某种方式为每个控制台提供补丁
sys
。
sys.stdout
这些似乎不是什么好主意。还有更好的吗?
如果您对单一进程死心塌地,那么根据您是否愿意深入研究 CPython 实现的晦涩的 C 级特性,您可以尝试研究 subinterpreters。据我所知,这些是 CPython 在单个进程中提供的最高级别的隔离,它们允许为单独的子解释器提供单独的 sys.stdout
对象。