我导入了readline,为我的程序添加了自定义标签。现在我需要保存程序的输出,但任何重定向stdout的尝试都会破坏标签完成功能。
我试过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')
答案 0 :(得分:0)
这是一个可能的解决方案:“猴子补丁”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')