python twisted模块_Python Twisted与Cmd模块的集成

I like Python's Twisted and Cmd. I want to use them together.

I got some things working, but so far I haven't figured out how to make tab-completion work, because I don't see how to receive tab keypres events right away (without pressing Enter) in Twisted's LineReceiver.

Here's my code so far:

#!/usr/bin/env python

from cmd import Cmd

from twisted.internet import reactor

from twisted.internet.stdio import StandardIO

from twisted.protocols.basic import LineReceiver

class CommandProcessor(Cmd):

def do_EOF(self, line):

return True

class LineProcessor(LineReceiver):

from os import linesep as delimiter # makes newline work

def __init__(self):

self.processor = CommandProcessor()

self.setRawMode()

def connectionMade(self):

self.transport.write('>>> ')

def rawDataReceived(self, data):

self.processor.onecmd(data)

self.transport.write('>>> ')

StandardIO(LineProcessor())

reactor.run()

Apart from tab completion, this somewhat works. I can enter a command like "help" and the Cmd module will print the results. But I've lost the nifty tab-complete functionality of the Cmd module, because Twisted is buffering one line at a time. I tried setting LineProcessor.delimiter to the empty string, to no avail. Maybe I need to find some other piece of Twisted to use instead of LineReceiver? Or maybe there's a simpler approach that will avoid my having to process every character one-by-one?

I can't use Cmd alone, because I want to make this a network application, where some commands will result in sending data, and receiving data from the network will happen asynchronously (and be displayed to the user).

So whether we start from the above code or something completely different, I'd like to build a nice, friendly terminal application in Python that responds to network events and also to tab completion. I hope I can use what's already out there and not have to implement too much myself.

解决方案

You have a couple of difficulties with this approach:

Cmd.onecmd is not going to do any tab processing.

Even if it did, your terminal needs to be in cbreak mode in order for individual keystrokes to make it to the Python interpreter (tty.setcbreak can take care of that).

As you know, Cmd.cmdloop is not reactor aware and will block waiting for input.

Yet, to get all of the cool line-editing you want, Cmd (actually readline) needs to have direct access to stdin and stdout.

Given all of these difficulties, you might want to look at letting the CommandProcessor run in its own thread. For example:

#!/usr/bin/env python

from cmd import Cmd

from twisted.internet import reactor

class CommandProcessor(Cmd):

def do_EOF(self, line):

return True

def do_YEP(self, line):

reactor.callFromThread(on_main_thread, "YEP")

def do_NOPE(self, line):

reactor.callFromThread(on_main_thread, "NOPE")

def on_main_thread(item):

print "doing", item

def heartbeat():

print "heartbeat"

reactor.callLater(1.0, heartbeat)

reactor.callLater(1.0, heartbeat)

reactor.callInThread(CommandProcessor().cmdloop)

reactor.run()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值