Python Cmdインスタンスを別のスレッドで実行し、プログラムの他の部分から入力を書き込んだり、出力を読み取ったりできるようにしたいと考えています。Cmd のコンストラクタでは、stdin(デフォルト: sys.stdin) と stdout(デフォルト sys.stdout) を指定することができます。読み取りと書き込みにStringIOモジュールを使用できると思っていましたが、Cmd は最初の文字列を読み取り、EOF に達して終了します。sys.stdin と同じ動作が必要なため、readline() は、読み取る入力があるまでブロックされます。
私はこのクラスを作りました。これは私が望むように動作します:
import Queue
class BlockingLineIO():
def __init__(self):
self.closed = False
self.queue = Queue.Queue()
self.remainder = ""
def write(self, s):
for line in s.splitlines(True):
if not line.endswith("\n"):
self.remainder = line
elif line != "":
self.queue.put(self.remainder + line)
self.remainder = ""
def read(self):
if self.queue.empty() and self.closed:
return ""
else:
self.queue.put(False)
return "".join(list(iter(self.queue.get, False)))
def readline(self):
if self.queue.empty() and self.closed:
return ""
else:
return self.queue.get()
def flush(self):
pass
def close(self):
self.queue.put("")
self.closed = True
def main():
import cmd, threading
my_cmd_class = type("Foo", (cmd.Cmd, object),
{'do_EOF': lambda self, line: self.stdout.write("Bye.\n") == None})
my_cmd = my_cmd_class(stdin=BlockingLineIO(), stdout=BlockingLineIO())
my_cmd.use_rawinput = False
my_cmd.prompt = ""
cmd_loop = threading.Thread(target=my_cmd.cmdloop)
cmd_loop.start()
my_cmd.stdin.write("help\n")
print my_cmd.stdout.readline()
print my_cmd.stdout.read()
my_cmd.stdin.close()
cmd_loop.join()
print my_cmd.stdout.read()
if __name__ == '__main__':
main()
質問:
上記は私が必要とするものを達成するための通常の方法ですか? stdin と stdout のパイプに使用する標準クラスはありますか? 何かが欠けているような気がします。