[英]Python module “readline” can't handle output redirection
我導入了readline,為我的程序添加了自定義選項卡。 現在我需要保存程序的輸出,但任何重定向stdout的嘗試都會破壞選項卡完成功能。
我試過python3 script.py | tee txt.txt
python3 script.py | tee txt.txt
女巫似乎最接近打印到stdout和文本文件,但它不起作用。
這是自定義選項卡完成類,帶有來自main的函數調用(以防萬一):
import readline
class MyCompleter(object):
def __init__(self, options):
self.options = sorted(options)
def complete(self, text, state):
if state == 0:
if text:
self.matches = [s for s in self.options if s and s.startswith(text)]
else:
self.matches = self.options[:]
try:
return self.matches[state]
except IndexError:
return None
def readlineset(a): # function called from main to turn on tab completion
# a is list of strings
readline.set_completer(MyCompleter(a).complete)
readline.parse_and_bind('tab: complete')
這是一個可能的解決方案:“猴子補丁” sys.stdout.write
方法,以便寫入stdout
任何內容也會被發送到文件。 我承認這不是很優雅,但它確實有效。 ;)
我已將Logger
類設置為Context Manager,以便可以在with
語句中使用它。
import readline
import sys
class MyCompleter(object):
def __init__(self, options):
self.options = sorted(options)
def complete(self, text, state):
if state == 0:
if text:
self.matches = [s for s in self.options if s and s.startswith(text)]
else:
self.matches = self.options[:]
try:
return self.matches[state]
except IndexError:
return None
class Logger(object):
''' Monkey-patch sys.stdout
to copy output to a file
'''
def __init__(self, fname):
self.fh = open(fname, 'w')
self.oldwrite = sys.stdout.write
sys.stdout.write = self.write
def write(self, s):
self.oldwrite(s)
self.fh.write(s)
def close(self):
self.fh.close()
sys.stdout.write = self.oldwrite
# Define Context Manager methods so Logger
# can be used in a `with` statement
def __enter__(self):
return self
def __exit__(self, *args):
self.close()
return False
def readlineset(a):
''' Turn on tab completion.
`a` is list of strings that will be completed
'''
readline.set_completer(MyCompleter(a).complete)
readline.parse_and_bind('tab: complete')
def main():
readlineset(['python', 'stack', 'overflow', 'exchange'])
with Logger('mylog.txt'):
while True:
s = input('> ')
if s == 'quit':
break
print(repr(s), len(s))
print('bye')
if __name__ == '__main__':
main()
演示
> This is a test
'This is a test' 14
> python on stack overflow
'python on stack overflow' 24
> quit
bye
mylog.txt
'This is a test' 14
'python on stack overflow' 24
如果你不希望使用with
,你可以使用Logger
是這樣的:
def main():
readlineset(['python', 'stack', 'overflow', 'exchange'])
logger = Logger('mylog.txt')
while True:
s = input('> ')
if s == 'quit':
break
print(repr(s), len(s))
logger.close()
print('bye')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.