除了脚本自己的控制台(什么都不做)之外,我想打开两个控制台并在不同的控制台中打印变量con1
,con2
我该如何实现这一点。
con1 = 'This is Console1'
con2 = 'This is Console2'
我不知道如何实现这一点,并且花了几个小时尝试使用诸如subprocess
但没有运气的模块来做到这一点。顺便说一句,我在窗户上。
编辑:
threading
模块能完成这项工作吗?还是multiprocessing
需要?
例如:
除了脚本自己的控制台(什么都不做)之外,我想打开两个控制台并在不同的控制台中打印变量con1
,con2
我该如何实现这一点。
con1 = 'This is Console1'
con2 = 'This is Console2'
我不知道如何实现这一点,并且花了几个小时尝试使用诸如subprocess
但没有运气的模块来做到这一点。顺便说一句,我在窗户上。
threading
模块能完成这项工作吗?还是multiprocessing
需要?
例如:
如果您不想重新考虑您的问题并使用@Kevin's answer中的GUI,那么您可以使用模块同时启动两个新控制台并在打开的窗口中显示两个给定的字符串:subprocess
#!/usr/bin/env python3
import sys
import time
from subprocess import Popen, PIPE, CREATE_NEW_CONSOLE
messages = 'This is Console1', 'This is Console2'
# open new consoles
processes = [Popen([sys.executable, "-c", """import sys
for line in sys.stdin: # poor man's `cat`
sys.stdout.write(line)
sys.stdout.flush()
"""],
stdin=PIPE, bufsize=1, universal_newlines=True,
# assume the parent script is started from a console itself e.g.,
# this code is _not_ run as a *.pyw file
creationflags=CREATE_NEW_CONSOLE)
for _ in range(len(messages))]
# display messages
for proc, msg in zip(processes, messages):
proc.stdin.write(msg + "\n")
proc.stdin.flush()
time.sleep(10) # keep the windows open for a while
# close windows
for proc in processes:
proc.communicate("bye\n")
这是一个不依赖于的简化版本CREATE_NEW_CONSOLE
:
#!/usr/bin/env python
"""Show messages in two new console windows simultaneously."""
import sys
import platform
from subprocess import Popen
messages = 'This is Console1', 'This is Console2'
# define a command that starts new terminal
if platform.system() == "Windows":
new_window_command = "cmd.exe /c start".split()
else: #XXX this can be made more portable
new_window_command = "x-terminal-emulator -e".split()
# open new consoles, display messages
echo = [sys.executable, "-c",
"import sys; print(sys.argv[1]); input('Press Enter..')"]
processes = [Popen(new_window_command + echo + [msg]) for msg in messages]
# wait for the windows to be closed
for proc in processes:
proc.wait()
You can get something like two consoles using two Tkinter Text widgets.
from Tkinter import *
import threading
class FakeConsole(Frame):
def __init__(self, root, *args, **kargs):
Frame.__init__(self, root, *args, **kargs)
#white text on black background,
#for extra versimilitude
self.text = Text(self, bg="black", fg="white")
self.text.pack()
#list of things not yet printed
self.printQueue = []
#one thread will be adding to the print queue,
#and another will be iterating through it.
#better make sure one doesn't interfere with the other.
self.printQueueLock = threading.Lock()
self.after(5, self.on_idle)
#check for new messages every five milliseconds
def on_idle(self):
with self.printQueueLock:
for msg in self.printQueue:
self.text.insert(END, msg)
self.text.see(END)
self.printQueue = []
self.after(5, self.on_idle)
#print msg to the console
def show(self, msg, sep="\n"):
with self.printQueueLock:
self.printQueue.append(str(msg) + sep)
#warning! Calling this more than once per program is a bad idea.
#Tkinter throws a fit when two roots each have a mainloop in different threads.
def makeConsoles(amount):
root = Tk()
consoles = [FakeConsole(root) for n in range(amount)]
for c in consoles:
c.pack()
threading.Thread(target=root.mainloop).start()
return consoles
a,b = makeConsoles(2)
a.show("This is Console 1")
b.show("This is Console 2")
a.show("I've got a lovely bunch of cocounts")
a.show("Here they are standing in a row")
b.show("Lorem ipsum dolor sit amet")
b.show("consectetur adipisicing elit")
Result:
我不知道它是否适合你,但你可以使用 Windowsstart
命令打开两个 Python 解释器:
from subprocess import Popen
p1 = Popen('start c:\python27\python.exe', shell=True)
p2 = Popen('start c:\python27\python.exe', shell=True)
当然,现在 Python 以交互模式运行存在问题,这不是您想要的(您也可以将文件作为参数传递,该文件将被执行)。
在 Linux 上,我会尝试创建命名管道,将文件名传递给 python.exe 并将 python 命令写入该文件。“也许”它会起作用;)
但我不知道如何在 Windows 上创建命名管道。Windows API ...(填写自己)。
如果您在 Windows 上,您可以使用 win32console 模块为您的线程或子进程输出打开第二个控制台。如果您在 Windows 上,这是最简单和最简单的方法。
这是一个示例代码:
import win32console
import multiprocessing
def subprocess(queue):
win32console.FreeConsole() #Frees subprocess from using main console
win32console.AllocConsole() #Creates new console and all input and output of subprocess goes to this new console
while True:
print(queue.get())
#prints any output produced by main script passed to subprocess using queue
queue = multiprocessing.Queue()
multiprocessing.Process(Target=subprocess, args=[queue]).start()
while True:
print("Hello World")
#and whatever else you want to do in ur main process
您也可以使用线程来执行此操作。如果您想要队列功能,则必须使用队列模块,因为线程模块没有队列
pymux
pymux 接近你想要的:https ://github.com/jonathanslenders/pymux
不幸的是,它主要是 CLI 工具的替代品tmux
,还没有像样的编程 API。
但是,如果您对此很认真,那么破解它以公开该 API 可能是最强大的选择。
自述文件说:
pymux 的一部分可以成为一个库,因此任何 prompt_toolkit 应用程序都可以嵌入一个 vt100 终端。(想象一下嵌入在 pyvim 中的终端仿真器。)
我使用了 jfs 的回应。这是我对 jfs 响应的点缀/盗窃。这是为在 Win10 上运行而量身定制的,并且还处理 Unicode:
# https://stackoverflow.com/questions/19479504/how-can-i-open-two-consoles-from-a-single-script
import sys, time, os, locale
from subprocess import Popen, PIPE, CREATE_NEW_CONSOLE
class console(Popen) :
NumConsoles = 0
def __init__(self, color=None, title=None):
console.NumConsoles += 1
cmd = "import sys, os, locale"
cmd += "\nos.system(\'color " + color + "\')" if color is not None else ""
title = title if title is not None else "console #" + str(console.NumConsoles)
cmd += "\nos.system(\"title " + title + "\")"
# poor man's `cat`
cmd += """
print(sys.stdout.encoding, locale.getpreferredencoding() )
endcoding = locale.getpreferredencoding()
for line in sys.stdin:
sys.stdout.buffer.write(line.encode(endcoding))
sys.stdout.flush()
"""
cmd = sys.executable, "-c", cmd
# print(cmd, end="", flush=True)
super().__init__(cmd, stdin=PIPE, bufsize=1, universal_newlines=True, creationflags=CREATE_NEW_CONSOLE, encoding='utf-8')
def write(self, msg):
self.stdin.write(msg + "\n" )
if __name__ == "__main__":
myConsole = console(color="c0", title="test error console")
myConsole.write("Thank you jfs. Cool explanation")
NoTitle= console()
NoTitle.write("default color and title! This answer uses Windows 10")
NoTitle.write(u"♥♥♥♥♥♥♥♥")
NoTitle.write("♥")
time.sleep(5)
myConsole.terminate()
NoTitle.write("some more text. Run this at the python console.")
time.sleep(4)
NoTitle.terminate()
time.sleep(5)
你知道screen/tmux吗?
tmuxp怎么样?例如,您可以尝试cat
在拆分窗格中运行并使用“sendkeys”发送输出(但请挖掘文档,可能有更简单的方法来实现这一点)。
作为附带奖励,这将在文本控制台或 GUI 中工作。