我制作了一个非常简单的交互式控制台,我想在复杂的抓取应用程序中使用它。它看起来像这样:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, sys, codecs, code
sys.__stdout__ = codecs.getwriter('utf8')(sys.__stdout__)
sys.__stderr__ = codecs.getwriter('utf8')(sys.__stderr__)
if 'DEBUG' in os.environ:
import pdb
import sys
oeh = sys.excepthook
def debug_exceptions(type, value, traceback):
pdb.post_mortem(traceback)
oeh(type, value, traceback)
sys.excepthook = debug_exceptions
class CLI(code.InteractiveConsole):
def __init__(self, locals=None, filename="<console>", histfile=None):
code.InteractiveConsole.__init__(self, locals, filename)
try:
import readline
except ImportError:
pass
else:
try:
import rlcompleter
readline.set_completer(rlcompleter.Completer(locals).complete)
except ImportError:
pass
readline.parse_and_bind("tab: complete")
self.interact()
if __name__ == "__main__":
hello="I am a local"
CLI(locals=locals())
如果我从另一个简单的应用程序调用它,它可以正常工作:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, sys, codecs, cli
sys.__stdout__ = codecs.getwriter('utf8')(sys.__stdout__)
sys.__stderr__ = codecs.getwriter('utf8')(sys.__stderr__)
from cli import CLI
foo="i am a local"
CLI(locals=locals())
但是,当我从我的基于twill和机械化的刮擦框架调用它时(虽然我打算将它切换到gevent)当以完全相同的方式调用CLI时,箭头键不起作用,制表符完成不起作用,实际上它的行为就像readline不存在一样。我已经尝试重新加载readline模块并直接传递它parse_and_bind命令,但由于某种原因它只是无法正常播放。关于什么已被破坏的任何提示或建议阻止它按预期工作,或者我只是必须删除所有正在使用的外部模块并将它们放入,一个接一个地看看发生了什么?
我怀疑twill看到它有自己的基本CLI,但如果有人知道我会很高兴知道是否有人知道发生了什么。
哦,请不要评论我正在用stderr和stdout做什么,它只是将样板代码放入python文件中,我总是从utf8控制台运行它们并不是我要问的...... < / p>
答案 0 :(得分:3)
好的,我发现造成这个问题的是我的问题,我之前使用过的旧版锅炉代码,我注意到它在某些情况下会引起问题:
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
sys.stderr = codecs.getwriter('utf8')(sys.stderr)
旧代码仍存在于我自己的一个文件中,将该代码更改为较低级别的版本:
sys.__stdout__ = codecs.getwriter('utf8')(sys.__stdout__)
sys.__stderr__ = codecs.getwriter('utf8')(sys.__stderr__)
或完全删除它,因为它不需要在该文件中解决问题。